Other: Fix race condition when changing address mode

When changing address mode, we would close all a user's update channels
and create them from scratch. This involved setting user.updateCh to a
new value. However, it was possible for other goroutines to read from
user.updateCh during this time. I replaced it with a call to
user.updateCh.Clear(), which is threadsafe.
This commit is contained in:
James Houlahan
2022-10-25 12:53:12 +02:00
parent dabc9717d1
commit 14fbdb5e04
2 changed files with 11 additions and 5 deletions

View File

@ -238,24 +238,22 @@ func (user *User) SetAddressMode(ctx context.Context, mode vault.AddressMode) er
}
})
updateCh := make(map[string]*queue.QueuedChannel[imap.Update])
user.updateCh.Clear()
switch mode {
case vault.CombinedMode:
primaryUpdateCh := queue.NewQueuedChannel[imap.Update](0, 0)
user.apiAddrs.IterKeys(func(addrID string) {
updateCh[addrID] = primaryUpdateCh
user.updateCh.Set(addrID, primaryUpdateCh)
})
case vault.SplitMode:
user.apiAddrs.IterKeys(func(addrID string) {
updateCh[addrID] = queue.NewQueuedChannel[imap.Update](0, 0)
user.updateCh.Set(addrID, queue.NewQueuedChannel[imap.Update](0, 0))
})
}
user.updateCh = safe.NewMapFrom(updateCh, nil)
if err := user.vault.SetAddressMode(mode); err != nil {
return fmt.Errorf("failed to set address mode: %w", err)
}