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")
|
logrus.WithError(rerr).Error("Failed to report feedback failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
user.BadEventFeedbackResync(ctx)
|
|
||||||
|
|
||||||
if err := bridge.addIMAPUser(ctx, user); err != nil {
|
if err := bridge.addIMAPUser(ctx, user); err != nil {
|
||||||
return fmt.Errorf("failed to add IMAP user: %w", err)
|
return fmt.Errorf("failed to add IMAP user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.BadEventFeedbackResync(ctx)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ func (bridge *Bridge) handleUserEvent(ctx context.Context, user *user.User, even
|
|||||||
}
|
}
|
||||||
|
|
||||||
case events.UserRefreshed:
|
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)
|
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
|
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 {
|
return safe.RLockRet(func() error {
|
||||||
|
if event.CancelEventPool {
|
||||||
|
user.CancelSyncAndEventPoll()
|
||||||
|
}
|
||||||
|
|
||||||
if err := bridge.removeIMAPUser(ctx, user, true); err != nil {
|
if err := bridge.removeIMAPUser(ctx, user, true); err != nil {
|
||||||
return fmt.Errorf("failed to remove IMAP user: %w", err)
|
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")
|
logrus.WithError(rerr).Error("Failed to report failed event handling")
|
||||||
}
|
}
|
||||||
|
|
||||||
user.BadEventAbort()
|
user.CancelSyncAndEventPoll()
|
||||||
|
|
||||||
// Disable IMAP user
|
// Disable IMAP user
|
||||||
if err := bridge.removeIMAPUser(context.Background(), user, false); err != nil {
|
if err := bridge.removeIMAPUser(context.Background(), user, false); err != nil {
|
||||||
|
|||||||
@ -149,6 +149,7 @@ type UserRefreshed struct {
|
|||||||
eventBase
|
eventBase
|
||||||
|
|
||||||
UserID string
|
UserID string
|
||||||
|
CancelEventPool bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (event UserRefreshed) String() string {
|
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.
|
// Re-sync messages after the user, address and label refresh.
|
||||||
defer user.goSync()
|
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 {
|
return safe.LockRet(func() error {
|
||||||
// Fetch latest user info.
|
// Fetch latest user info.
|
||||||
apiUser, err := user.client.GetUser(ctx)
|
apiUser, err := user.client.GetUser(ctx)
|
||||||
@ -129,6 +129,7 @@ func (user *User) syncUserAddressesLabelsAndClearSync(ctx context.Context) error
|
|||||||
// The user was refreshed.
|
// The user was refreshed.
|
||||||
user.eventCh.Enqueue(events.UserRefreshed{
|
user.eventCh.Enqueue(events.UserRefreshed{
|
||||||
UserID: user.apiUser.ID,
|
UserID: user.apiUser.ID,
|
||||||
|
CancelEventPool: cancelEventPool,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -299,15 +299,19 @@ func (user *User) SetAddressMode(_ context.Context, mode vault.AddressMode) erro
|
|||||||
}, user.eventLock, user.apiAddrsLock, user.updateChLock)
|
}, user.eventLock, user.apiAddrsLock, user.updateChLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadEventAbort stops user to communicate. The resolution is either logout or resync.
|
// CancelSyncAndEventPoll stops the sync or event poll go-routine.
|
||||||
func (user *User) BadEventAbort() {
|
func (user *User) CancelSyncAndEventPoll() {
|
||||||
user.syncAbort.Abort()
|
user.syncAbort.Abort()
|
||||||
user.pollAbort.Abort()
|
user.pollAbort.Abort()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadEventFeedbackResync sends user feedback whether should do message re-sync.
|
// BadEventFeedbackResync sends user feedback whether should do message re-sync.
|
||||||
func (user *User) BadEventFeedbackResync(ctx context.Context) {
|
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")
|
user.log.WithError(err).Error("Bad event resync failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user