forked from Silverfish/proton-bridge
fix(GODT-2442): Handle event poll not starting after resync
It is possible, on slower machines, that the new event poll task is not yet registered and attempts to cancel have nothing to cancel. In this case, we need the refresh event to cancel the task, at that point it is guaranteed that the task exists.
This commit is contained in:
@ -326,12 +326,12 @@ func (bridge *Bridge) SendBadEventUserFeedback(_ context.Context, userID string,
|
||||
logrus.WithError(rerr).Error("Failed to report feedback failure")
|
||||
}
|
||||
|
||||
user.BadEventFeedbackResync(ctx)
|
||||
|
||||
if err := bridge.addIMAPUser(ctx, user); err != nil {
|
||||
return fmt.Errorf("failed to add IMAP user: %w", err)
|
||||
}
|
||||
|
||||
user.BadEventFeedbackResync(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ func (bridge *Bridge) handleUserEvent(ctx context.Context, user *user.User, even
|
||||
}
|
||||
|
||||
case events.UserRefreshed:
|
||||
if err := bridge.handleUserRefreshed(ctx, user); err != nil {
|
||||
if err := bridge.handleUserRefreshed(ctx, user, event); err != nil {
|
||||
return fmt.Errorf("failed to handle user refreshed event: %w", err)
|
||||
}
|
||||
|
||||
@ -120,8 +120,12 @@ func (bridge *Bridge) handleUserAddressDeleted(ctx context.Context, user *user.U
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bridge *Bridge) handleUserRefreshed(ctx context.Context, user *user.User) error {
|
||||
func (bridge *Bridge) handleUserRefreshed(ctx context.Context, user *user.User, event events.UserRefreshed) error {
|
||||
return safe.RLockRet(func() error {
|
||||
if event.CancelEventPool {
|
||||
user.CancelSyncAndEventPoll()
|
||||
}
|
||||
|
||||
if err := bridge.removeIMAPUser(ctx, user, true); err != nil {
|
||||
return fmt.Errorf("failed to remove IMAP user: %w", err)
|
||||
}
|
||||
@ -153,7 +157,7 @@ func (bridge *Bridge) handleUserBadEvent(_ context.Context, user *user.User, eve
|
||||
logrus.WithError(rerr).Error("Failed to report failed event handling")
|
||||
}
|
||||
|
||||
user.BadEventAbort()
|
||||
user.CancelSyncAndEventPoll()
|
||||
|
||||
// Disable IMAP user
|
||||
if err := bridge.removeIMAPUser(context.Background(), user, false); err != nil {
|
||||
|
||||
@ -149,6 +149,7 @@ type UserRefreshed struct {
|
||||
eventBase
|
||||
|
||||
UserID string
|
||||
CancelEventPool bool
|
||||
}
|
||||
|
||||
func (event UserRefreshed) String() string {
|
||||
|
||||
@ -93,10 +93,10 @@ func (user *User) handleRefreshEvent(ctx context.Context, refresh proton.Refresh
|
||||
// Re-sync messages after the user, address and label refresh.
|
||||
defer user.goSync()
|
||||
|
||||
return user.syncUserAddressesLabelsAndClearSync(ctx)
|
||||
return user.syncUserAddressesLabelsAndClearSync(ctx, false)
|
||||
}
|
||||
|
||||
func (user *User) syncUserAddressesLabelsAndClearSync(ctx context.Context) error {
|
||||
func (user *User) syncUserAddressesLabelsAndClearSync(ctx context.Context, cancelEventPool bool) error {
|
||||
return safe.LockRet(func() error {
|
||||
// Fetch latest user info.
|
||||
apiUser, err := user.client.GetUser(ctx)
|
||||
@ -129,6 +129,7 @@ func (user *User) syncUserAddressesLabelsAndClearSync(ctx context.Context) error
|
||||
// The user was refreshed.
|
||||
user.eventCh.Enqueue(events.UserRefreshed{
|
||||
UserID: user.apiUser.ID,
|
||||
CancelEventPool: cancelEventPool,
|
||||
})
|
||||
|
||||
return nil
|
||||
|
||||
@ -299,15 +299,19 @@ func (user *User) SetAddressMode(_ context.Context, mode vault.AddressMode) erro
|
||||
}, user.eventLock, user.apiAddrsLock, user.updateChLock)
|
||||
}
|
||||
|
||||
// BadEventAbort stops user to communicate. The resolution is either logout or resync.
|
||||
func (user *User) BadEventAbort() {
|
||||
// CancelSyncAndEventPoll stops the sync or event poll go-routine.
|
||||
func (user *User) CancelSyncAndEventPoll() {
|
||||
user.syncAbort.Abort()
|
||||
user.pollAbort.Abort()
|
||||
}
|
||||
|
||||
// BadEventFeedbackResync sends user feedback whether should do message re-sync.
|
||||
func (user *User) BadEventFeedbackResync(ctx context.Context) {
|
||||
if err := user.syncUserAddressesLabelsAndClearSync(ctx); err != nil {
|
||||
user.CancelSyncAndEventPoll()
|
||||
|
||||
// We need to cancel the event poll later again as it is not guaranteed, due to timing, that we have a
|
||||
// task to cancel.
|
||||
if err := user.syncUserAddressesLabelsAndClearSync(ctx, true); err != nil {
|
||||
user.log.WithError(err).Error("Bad event resync failed")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user