Skip to content

Move execution ack off of the critical path#4816

Draft
joshua-spacetime wants to merge 1 commit intojoshua/keep-subscription-fanout-busyfrom
joshua/move-reducer-reply-off-critical-path
Draft

Move execution ack off of the critical path#4816
joshua-spacetime wants to merge 1 commit intojoshua/keep-subscription-fanout-busyfrom
joshua/move-reducer-reply-off-critical-path

Conversation

@joshua-spacetime
Copy link
Copy Markdown
Collaborator

Description of Changes

Today, for each client connection, we process requests one at a time, and we wait for each request to finish before processing the next one. The way this works is that each websocket reader waits for a notification (via a one shot channel) from the JS worker that it is done processing the request. This notification is quite costly because it always wakes the receiving task.

To avoid this costly wake, this patch adds an intermediate relay actor. The relay reads from its message queue periodically and forwards the replies on to the correct websocket reader task. This trades latency for increased throughput.

I would classify this as a hack, and so I'm not sure I would recommend merging this. A potentially better solution would be to remove the reply altogether. However if we want to preserve execution order per connection, I'm not sure if this is possible today, because I'm not sure if we have a single serialization point for all requests. But I think it is ultimately the direction we want to go.

API and ABI breaking changes

None

Expected complexity level and risk

1

Testing

Manual

Copy link
Copy Markdown
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

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

Looks OK, just some nits.

I'm fine with merging this in the interest of perf. It's not that bad for now.

} => {
let res = instance_common.update_database(program, old_module_info, policy, &mut inst);
send_worker_reply("update_database", reply_tx, res);
send_worker_reply(reply_relay.as_ref(), "update_database", reply_tx, res);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you do this once at the top of the function so that the .as_ref() noise is removed?

// Convert program to a string.
let program: Arc<str> = str::from_utf8(program_bytes)?.into();
let database_identity = mcc.replica_ctx.database_identity;
let lane_queue = JsWorkerQueue::unbounded_with_metric(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
let lane_queue = JsWorkerQueue::unbounded_with_metric(

The paragraph comment "Convert program to a string." now also includes unrelated code. Let's fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants