-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
refactor: S3 batch export with SPMC abstractions #26577
refactor: S3 batch export with SPMC abstractions #26577
Conversation
@@ -199,6 +211,7 @@ def __init__( | |||
self.kms_key_id = kms_key_id | |||
self.upload_id: str | None = None | |||
self.parts: list[Part] = [] | |||
self.pending_parts: list[Part] = [] |
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.
Without this, we could run into concurrency problems: As we only append a part to self.parts
after it has been sent. Imagine the following (very realistic) sequence of events with just 2 consumers:
- Consumer 1 starts, gets assigned part 1 by
self.part_number+1
asself.parts
is empty. - Consumer 1 relinquishes control back to main loop on awaiting
self.upload_part_retryable
. - Consumer 2 starts, gets assigned part 1 by
self.part_number+1
asself.parts
is still empty. - Consumer 2 relinquishes control back to main loop on awaiting
self.upload_part_retryable
. - Consumer 1 resumes, appends part 1 to
self.parts
, and finishes. - Consumer 2 resumes, appends part 1 to
self.parts
, and finishes.
We have ended with two parts with part number 1, which means whichever consumer uploaded last would have overridden the other in the upload.
With the addition of self.pending_parts
we can "lock" any part numbers in progress so that they don't get repeated when doing self.part_number+1
.
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.
thanks for the explanation 👍
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.
LGTM
1b49560
to
c6534c8
Compare
Suspect IssuesThis pull request was deployed and Sentry observed the following issues:
Did you find this useful? React with a 👍 or 👎 |
Problem
Builds on top of #26575 to refactor S3 batch export to use fully-async SPMC abstractions. Big part of the work was done in the linked PR, so there isn't much to do here.
Changes
S3Consumer
classS3Consumer
.S3Consumer
withrun_consumer_loop
in S3 batch export.events_recent
view in spmc, as that was missing from my other PR.The implementation does have a potential concurrency conflict when computing the
next_part_number
that I think to have resolved by using a newpending_parts
.👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Does this work well for both Cloud and self-hosted?
How did you test this code?