Skip to content
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

Run order events insertion in parallel #2131

Merged
merged 5 commits into from
Dec 7, 2023

Conversation

squadgazzz
Copy link
Contributor

Description

Executes order events db insert operation in parallel in order to propagate the auction among solvers as soon as possible. The same approach could be used in other parts of the application since this operation takes a while.

How to test

Logs observation

Related Issues

Relates to #2095

@squadgazzz squadgazzz marked this pull request as ready for review December 6, 2023 19:19
@squadgazzz squadgazzz requested a review from a team as a code owner December 6, 2023 19:19
Copy link
Contributor

@MartinquaXD MartinquaXD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit torn on this. On the one hand moving stuff in the background makes the critical path faster. On the other hand we are about to merge the optimization that we only store events for market orders so we'd get rid of many inserts here.

One thing that is very interesting to me is that it looks like inserting events here can take from anywhere between 10ms and 1.5s for prod mainnet so even if we have only a few events to insert we might trigger some pathological behavior which we should move off of the critical path.

Edit: Only noticed after digging more through GH that you already wrote a comment somewhere else explaining your findings.

Comment on lines 361 to 363
if let Err(err) = store_order_events_f.await {
tracing::warn!(auction_id=%id, ?err, "failed to store order events")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep the diff of the PR smaller and the code easier to read I'd suggest simply spawning the task and forgetting about it. This debugging data is not critical and having an error here is not very relevant. Also the future itself already handles it's own error so we'd only handle tokio runtime errors here which we can probably not do anything about anyway.
That way you can keep most of this code unchanged.

let store_order_events_f = tokio::spawn(async move {
let start = Instant::now();
db.store_order_events(&events).await;
tracing::debug!(elapsed=?start.elapsed(), aution_id=%id, "storing order events took");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to note here is that when you spawn a new task you lose the tracing context of the task you spawned it from. To keep it around you have to do sth like:

tokio::task::spawn(future.instrument(tracing::Span::current()));
Suggested change
tracing::debug!(elapsed=?start.elapsed(), aution_id=%id, "storing order events took");
tracing::debug!(elapsed=?start.elapsed(), "stored order events");

@squadgazzz
Copy link
Contributor Author

I'm a bit torn on this. On the one hand moving stuff in the background makes the critical path faster. On the other hand we are about to merge the optimization that we only store events for market orders so we'd get rid of many inserts here.
One thing that is very interesting to me is that it looks like inserting events here can take from anywhere between 10ms and 1.5s for prod mainnet so even if we have only a few events to insert we might trigger some pathological behavior which we should move off of the critical path.

From the comment, I understood that the proposed improvement for Market orders should be reconsidered and it doesn't make any sense to merge the current implementation.

async move {
let start = Instant::now();
db.store_order_events(&events).await;
tracing::debug!(elapsed=?start.elapsed(), events_count=events.len(), "stored order events");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does tracing span include the auction id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe, it should:

self.single_run(id, auction)
.instrument(tracing::info_span!("auction", id))
.await;

.iter()
.map(|o| (o.metadata.uid, OrderEventLabel::Ready))
.collect_vec();
tokio::spawn(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: comment on why we spawn a new task here

@squadgazzz squadgazzz enabled auto-merge (squash) December 7, 2023 17:41
@squadgazzz squadgazzz merged commit 2f8b38e into main Dec 7, 2023
8 checks passed
@squadgazzz squadgazzz deleted the run-events-insertion-in-parallel branch December 7, 2023 17:45
@github-actions github-actions bot locked and limited conversation to collaborators Dec 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants