diff --git a/internal/bridge/bridge.go b/internal/bridge/bridge.go index c6efd9e8..07e29c81 100644 --- a/internal/bridge/bridge.go +++ b/internal/bridge/bridge.go @@ -72,9 +72,14 @@ type Bridge struct { smtpListener net.Listener // updater is the bridge's updater. - updater Updater - curVersion *semver.Version - installCh chan installJob + updater Updater + installCh chan installJob + + // curVersion is the current version of the bridge, + // newVersion is the version that was installed by the updater. + curVersion *semver.Version + newVersion *semver.Version + newVersionLock safe.RWMutex // focusService is used to raise the bridge window when needed. focusService *focus.Service @@ -240,9 +245,12 @@ func newBridge( imapServer: imapServer, imapEventCh: imapEventCh, - updater: updater, - curVersion: curVersion, - installCh: make(chan installJob, 1), + updater: updater, + installCh: make(chan installJob), + + curVersion: curVersion, + newVersion: curVersion, + newVersionLock: safe.NewRWMutex(), focusService: focusService, autostarter: autostarter, diff --git a/internal/bridge/updates.go b/internal/bridge/updates.go index a2c15e81..478661cf 100644 --- a/internal/bridge/updates.go +++ b/internal/bridge/updates.go @@ -21,6 +21,7 @@ import ( "context" "github.com/ProtonMail/proton-bridge/v2/internal/events" + "github.com/ProtonMail/proton-bridge/v2/internal/safe" "github.com/ProtonMail/proton-bridge/v2/internal/updater" "github.com/sirupsen/logrus" ) @@ -86,21 +87,19 @@ func (bridge *Bridge) handleUpdate(version updater.VersionInfo) { }) default: - log.Info("An update is available") + safe.RLock(func() { + if version.Version.GreaterThan(bridge.newVersion) { + log.Info("An update is available") - bridge.publish(events.UpdateAvailable{ - Version: version, - Compatible: true, - Silent: true, - }) + select { + case bridge.installCh <- installJob{version: version, silent: true}: + log.Info("The update will be installed silently") - select { - case bridge.installCh <- installJob{version: version, silent: true}: - log.Info("The update will be installed silently") - - default: - log.Info("An update is already being installed") - } + default: + log.Info("An update is already being installed") + } + } + }, bridge.newVersionLock) } } @@ -110,31 +109,41 @@ type installJob struct { } func (bridge *Bridge) installUpdate(ctx context.Context, job installJob) { - log := logrus.WithFields(logrus.Fields{ - "version": job.version.Version, - "current": bridge.curVersion, - "channel": bridge.vault.GetUpdateChannel(), - }) - - bridge.publish(events.UpdateInstalling{ - Version: job.version, - Silent: job.silent, - }) - - if err := bridge.updater.InstallUpdate(ctx, bridge.api, job.version); err != nil { - log.Error("The update could not be installed") - - bridge.publish(events.UpdateFailed{ - Version: job.version, - Silent: job.silent, - Error: err, + safe.Lock(func() { + log := logrus.WithFields(logrus.Fields{ + "version": job.version.Version, + "current": bridge.curVersion, + "channel": bridge.vault.GetUpdateChannel(), }) - } else { - log.Info("The update was installed successfully") - bridge.publish(events.UpdateInstalled{ + bridge.publish(events.UpdateAvailable{ + Version: job.version, + Compatible: true, + Silent: job.silent, + }) + + bridge.publish(events.UpdateInstalling{ Version: job.version, Silent: job.silent, }) - } + + if err := bridge.updater.InstallUpdate(ctx, bridge.api, job.version); err != nil { + log.Error("The update could not be installed") + + bridge.publish(events.UpdateFailed{ + Version: job.version, + Silent: job.silent, + Error: err, + }) + } else { + log.Info("The update was installed successfully") + + bridge.publish(events.UpdateInstalled{ + Version: job.version, + Silent: job.silent, + }) + + bridge.newVersion = job.version.Version + } + }, bridge.newVersionLock) } diff --git a/internal/events/update.go b/internal/events/update.go index 7cdf73bd..6d5b0c36 100644 --- a/internal/events/update.go +++ b/internal/events/update.go @@ -109,5 +109,5 @@ type UpdateForced struct { } func (event UpdateForced) String() string { - return fmt.Sprintf("UpdateForced") + return "UpdateForced" }