mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-11 05:06:51 +00:00
Other: Stop gRPC server on crash
This commit is contained in:
committed by
Leander Beernaert
parent
f954f89747
commit
6bd8c6ceb6
@ -180,7 +180,7 @@ func run(c *cli.Context) error { //nolint:funlen
|
|||||||
// Restart the app if requested.
|
// Restart the app if requested.
|
||||||
return withRestarter(exe, func(restarter *restarter.Restarter) error {
|
return withRestarter(exe, func(restarter *restarter.Restarter) error {
|
||||||
// Handle crashes with various actions.
|
// Handle crashes with various actions.
|
||||||
return withCrashHandler(restarter, reporter, func(crashHandler *crash.Handler) error {
|
return withCrashHandler(restarter, reporter, func(crashHandler *crash.Handler, quitCh <-chan struct{}) error {
|
||||||
// Load the locations where we store our files.
|
// Load the locations where we store our files.
|
||||||
return WithLocations(func(locations *locations.Locations) error {
|
return WithLocations(func(locations *locations.Locations) error {
|
||||||
// Migrate the keychain helper.
|
// Migrate the keychain helper.
|
||||||
@ -231,7 +231,7 @@ func run(c *cli.Context) error { //nolint:funlen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the frontend.
|
// Run the frontend.
|
||||||
return runFrontend(c, crashHandler, restarter, locations, b, eventCh, c.Int(flagParentPID))
|
return runFrontend(c, crashHandler, restarter, locations, b, eventCh, quitCh, c.Int(flagParentPID))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -246,6 +246,7 @@ func run(c *cli.Context) error { //nolint:funlen
|
|||||||
// If there's another instance already running, try to raise it and exit.
|
// If there's another instance already running, try to raise it and exit.
|
||||||
func withSingleInstance(locations *locations.Locations, version *semver.Version, fn func() error) error {
|
func withSingleInstance(locations *locations.Locations, version *semver.Version, fn func() error) error {
|
||||||
logrus.Debug("Checking for other instances")
|
logrus.Debug("Checking for other instances")
|
||||||
|
defer logrus.Debug("Single instance stopped")
|
||||||
|
|
||||||
lock, err := checkSingleInstance(locations.GetLockFile(), version)
|
lock, err := checkSingleInstance(locations.GetLockFile(), version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -271,13 +272,16 @@ func withSingleInstance(locations *locations.Locations, version *semver.Version,
|
|||||||
|
|
||||||
// Initialize our logging system.
|
// Initialize our logging system.
|
||||||
func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locations.Locations, fn func() error) error {
|
func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locations.Locations, fn func() error) error {
|
||||||
|
logrus.Debug("Initializing logging")
|
||||||
|
defer logrus.Debug("Logging stopped")
|
||||||
|
|
||||||
// Get a place to keep our logs.
|
// Get a place to keep our logs.
|
||||||
logsPath, err := locations.ProvideLogsPath()
|
logsPath, err := locations.ProvideLogsPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not provide logs path: %w", err)
|
return fmt.Errorf("could not provide logs path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.WithField("path", logsPath).Debug("Initializing logging")
|
logrus.WithField("path", logsPath).Debug("Received logs path")
|
||||||
|
|
||||||
// Initialize logging.
|
// Initialize logging.
|
||||||
if err := logging.Init(logsPath, c.String(flagLogLevel)); err != nil {
|
if err := logging.Init(logsPath, c.String(flagLogLevel)); err != nil {
|
||||||
@ -302,6 +306,7 @@ func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locatio
|
|||||||
// WithLocations provides access to locations where we store our files.
|
// WithLocations provides access to locations where we store our files.
|
||||||
func WithLocations(fn func(*locations.Locations) error) error {
|
func WithLocations(fn func(*locations.Locations) error) error {
|
||||||
logrus.Debug("Creating locations")
|
logrus.Debug("Creating locations")
|
||||||
|
defer logrus.Debug("Locations stopped")
|
||||||
|
|
||||||
// Create a locations provider to determine where to store our files.
|
// Create a locations provider to determine where to store our files.
|
||||||
provider, err := locations.NewDefaultProvider(filepath.Join(constants.VendorName, constants.ConfigName))
|
provider, err := locations.NewDefaultProvider(filepath.Join(constants.VendorName, constants.ConfigName))
|
||||||
@ -322,6 +327,8 @@ func WithLocations(fn func(*locations.Locations) error) error {
|
|||||||
|
|
||||||
// Start profiling if requested.
|
// Start profiling if requested.
|
||||||
func withProfiler(c *cli.Context, fn func() error) error {
|
func withProfiler(c *cli.Context, fn func() error) error {
|
||||||
|
defer logrus.Debug("Profiler stopped")
|
||||||
|
|
||||||
if c.Bool(flagCPUProfile) {
|
if c.Bool(flagCPUProfile) {
|
||||||
logrus.Debug("Running with CPU profiling")
|
logrus.Debug("Running with CPU profiling")
|
||||||
defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
|
defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
|
||||||
@ -338,6 +345,7 @@ func withProfiler(c *cli.Context, fn func() error) error {
|
|||||||
// Restart the app if necessary.
|
// Restart the app if necessary.
|
||||||
func withRestarter(exe string, fn func(*restarter.Restarter) error) error {
|
func withRestarter(exe string, fn func(*restarter.Restarter) error) error {
|
||||||
logrus.Debug("Creating restarter")
|
logrus.Debug("Creating restarter")
|
||||||
|
defer logrus.Debug("Restarter stopped")
|
||||||
|
|
||||||
restarter := restarter.New(exe)
|
restarter := restarter.New(exe)
|
||||||
defer restarter.Restart()
|
defer restarter.Restart()
|
||||||
@ -346,8 +354,9 @@ func withRestarter(exe string, fn func(*restarter.Restarter) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle crashes if they occur.
|
// Handle crashes if they occur.
|
||||||
func withCrashHandler(restarter *restarter.Restarter, reporter *sentry.Reporter, fn func(*crash.Handler) error) error {
|
func withCrashHandler(restarter *restarter.Restarter, reporter *sentry.Reporter, fn func(*crash.Handler, <-chan struct{}) error) error {
|
||||||
logrus.Debug("Creating crash handler")
|
logrus.Debug("Creating crash handler")
|
||||||
|
defer logrus.Debug("Crash handler stopped")
|
||||||
|
|
||||||
crashHandler := crash.NewHandler(crash.ShowErrorNotification(constants.FullAppName))
|
crashHandler := crash.NewHandler(crash.ShowErrorNotification(constants.FullAppName))
|
||||||
defer crashHandler.HandlePanic()
|
defer crashHandler.HandlePanic()
|
||||||
@ -361,12 +370,19 @@ func withCrashHandler(restarter *restarter.Restarter, reporter *sentry.Reporter,
|
|||||||
// On crash, restart the app.
|
// On crash, restart the app.
|
||||||
crashHandler.AddRecoveryAction(func(any) error { restarter.Set(true, true); return nil })
|
crashHandler.AddRecoveryAction(func(any) error { restarter.Set(true, true); return nil })
|
||||||
|
|
||||||
return fn(crashHandler)
|
// quitCh is closed when the app is quitting.
|
||||||
|
quitCh := make(chan struct{})
|
||||||
|
|
||||||
|
// On crash, quit the app.
|
||||||
|
crashHandler.AddRecoveryAction(func(any) error { close(quitCh); return nil })
|
||||||
|
|
||||||
|
return fn(crashHandler, quitCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a custom cookie jar to persist values across runs.
|
// Use a custom cookie jar to persist values across runs.
|
||||||
func withCookieJar(vault *vault.Vault, fn func(http.CookieJar) error) error {
|
func withCookieJar(vault *vault.Vault, fn func(http.CookieJar) error) error {
|
||||||
logrus.Debug("Creating cookie jar")
|
logrus.Debug("Creating cookie jar")
|
||||||
|
defer logrus.Debug("Cookie jar stopped")
|
||||||
|
|
||||||
// Create the underlying cookie jar.
|
// Create the underlying cookie jar.
|
||||||
jar, err := cookiejar.New(nil)
|
jar, err := cookiejar.New(nil)
|
||||||
|
|||||||
@ -59,6 +59,7 @@ func withBridge( //nolint:funlen
|
|||||||
fn func(*bridge.Bridge, <-chan events.Event) error,
|
fn func(*bridge.Bridge, <-chan events.Event) error,
|
||||||
) error {
|
) error {
|
||||||
logrus.Debug("Creating bridge")
|
logrus.Debug("Creating bridge")
|
||||||
|
defer logrus.Debug("Bridge stopped")
|
||||||
|
|
||||||
// Delete old go-imap cache files
|
// Delete old go-imap cache files
|
||||||
if deleteOldGoIMAPFiles {
|
if deleteOldGoIMAPFiles {
|
||||||
|
|||||||
@ -38,8 +38,12 @@ func runFrontend(
|
|||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
bridge *bridge.Bridge,
|
bridge *bridge.Bridge,
|
||||||
eventCh <-chan events.Event,
|
eventCh <-chan events.Event,
|
||||||
|
quitCh <-chan struct{},
|
||||||
parentPID int,
|
parentPID int,
|
||||||
) error {
|
) error {
|
||||||
|
logrus.Debug("Running frontend")
|
||||||
|
defer logrus.Debug("Frontend stopped")
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case c.Bool(flagCLI):
|
case c.Bool(flagCLI):
|
||||||
return bridgeCLI.New(bridge, restarter, eventCh).Loop()
|
return bridgeCLI.New(bridge, restarter, eventCh).Loop()
|
||||||
@ -48,7 +52,7 @@ func runFrontend(
|
|||||||
select {}
|
select {}
|
||||||
|
|
||||||
case c.Bool(flagGRPC):
|
case c.Bool(flagGRPC):
|
||||||
service, err := grpc.NewService(crashHandler, restarter, locations, bridge, eventCh, !c.Bool(flagNoWindow), parentPID)
|
service, err := grpc.NewService(crashHandler, restarter, locations, bridge, eventCh, quitCh, !c.Bool(flagNoWindow), parentPID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create service: %w", err)
|
return fmt.Errorf("could not create service: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import (
|
|||||||
|
|
||||||
func WithVault(locations *locations.Locations, fn func(*vault.Vault, bool, bool) error) error {
|
func WithVault(locations *locations.Locations, fn func(*vault.Vault, bool, bool) error) error {
|
||||||
logrus.Debug("Creating vault")
|
logrus.Debug("Creating vault")
|
||||||
|
defer logrus.Debug("Vault stopped")
|
||||||
|
|
||||||
// Create the encVault.
|
// Create the encVault.
|
||||||
encVault, insecure, corrupt, err := newVault(locations)
|
encVault, insecure, corrupt, err := newVault(locations)
|
||||||
|
|||||||
@ -68,6 +68,7 @@ type Service struct { // nolint:structcheck
|
|||||||
restarter Restarter
|
restarter Restarter
|
||||||
bridge *bridge.Bridge
|
bridge *bridge.Bridge
|
||||||
eventCh <-chan events.Event
|
eventCh <-chan events.Event
|
||||||
|
quitCh <-chan struct{}
|
||||||
|
|
||||||
latest updater.VersionInfo
|
latest updater.VersionInfo
|
||||||
latestLock safe.RWMutex
|
latestLock safe.RWMutex
|
||||||
@ -97,6 +98,7 @@ func NewService(
|
|||||||
locations Locator,
|
locations Locator,
|
||||||
bridge *bridge.Bridge,
|
bridge *bridge.Bridge,
|
||||||
eventCh <-chan events.Event,
|
eventCh <-chan events.Event,
|
||||||
|
quitCh <-chan struct{},
|
||||||
showOnStartup bool,
|
showOnStartup bool,
|
||||||
parentPID int,
|
parentPID int,
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
@ -130,6 +132,7 @@ func NewService(
|
|||||||
restarter: restarter,
|
restarter: restarter,
|
||||||
bridge: bridge,
|
bridge: bridge,
|
||||||
eventCh: eventCh,
|
eventCh: eventCh,
|
||||||
|
quitCh: quitCh,
|
||||||
|
|
||||||
latest: updater.VersionInfo{},
|
latest: updater.VersionInfo{},
|
||||||
latestLock: safe.NewRWMutex(),
|
latestLock: safe.NewRWMutex(),
|
||||||
@ -194,6 +197,15 @@ func (s *Service) Loop() error {
|
|||||||
|
|
||||||
s.log.Info("Starting gRPC server")
|
s.log.Info("Starting gRPC server")
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
<-s.quitCh
|
||||||
|
|
||||||
|
s.log.Info("Stopping gRPC server")
|
||||||
|
defer s.log.Info("Stopped gRPC server")
|
||||||
|
|
||||||
|
s.grpcServer.Stop()
|
||||||
|
}()
|
||||||
|
|
||||||
if err := s.grpcServer.Serve(s.listener); err != nil {
|
if err := s.grpcServer.Serve(s.listener); err != nil {
|
||||||
s.log.WithError(err).Error("Failed to serve gRPC")
|
s.log.WithError(err).Error("Failed to serve gRPC")
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -202,6 +202,7 @@ func (t *testCtx) initFrontendService(eventCh <-chan events.Event) error {
|
|||||||
t.locator,
|
t.locator,
|
||||||
t.bridge,
|
t.bridge,
|
||||||
eventCh,
|
eventCh,
|
||||||
|
make(chan struct{}),
|
||||||
true,
|
true,
|
||||||
-1,
|
-1,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user