-
Notifications
You must be signed in to change notification settings - Fork 252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
send queue: make SendHandle::abort()
/update()
more precise
#3632
Conversation
Using `SendHandle::abort()` after the event has been sent would look like a successful abort of the event, while it's not the case; this fixes this by having the state store backends return whether they've touched an entry in the database.
SendHandle::abort()
/update()
more precise
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3632 +/- ##
==========================================
- Coverage 84.21% 84.18% -0.04%
==========================================
Files 256 256
Lines 26583 26593 +10
==========================================
Hits 22387 22387
- Misses 4196 4206 +10 ☔ View full report in Codecov by Sentry. |
There were two disconnected sources of truth for the state of event to be sent: - it can or cannot be in the in-memory `being_sent` map - it can or cannot be in the database Unfortunately, this led to subtle race conditions when it comes to editing/aborting. The following sequence of operations was possible: - try to send an event: a local echo is added to storage, but it's not marked as being sent yet - the task wakes up, finds the local echo in the storage,... - try to edit/abort the event: the event is not marked as being sent yet, so we think we can edit/abort it - ... having found the local echo, it is marked as being sent. This would result in the event misleadlingly not being aborted/edited, while it should have been. Now, there's already a lock on the `being_sent` map, so we can hold onto it while we're touching storage, making sure that there aren't two callers trying to manipulate storage *and* `being_sent` at the same time. This is pretty tricky to test properly, since this requires super precise timing control over the state store, so there's no test for this. I can confirm this avoids some weirdness I observed with `multiverse` though.
@@ -693,20 +708,22 @@ impl QueueStorage { | |||
&self, | |||
transaction_id: &TransactionId, | |||
) -> Result<bool, RoomSendQueueStorageError> { | |||
// Note: since there's a single caller (the room sending task, which processes | |||
// events to send linearly), there's no risk for race conditions here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trolololol
Using
SendHandle::abort()
after the event has been sent would look like a successful abort of the event, while it's not the case; this fixes this by having the state store backends return whether they've touched an entry in the database.Found thanks to
multiverse
.Part of #3361.