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

Rethinking CallAll::poll_next order of operations. #801

Open
geofmureithi opened this issue Dec 1, 2024 · 0 comments
Open

Rethinking CallAll::poll_next order of operations. #801

geofmureithi opened this issue Dec 1, 2024 · 0 comments

Comments

@geofmureithi
Copy link

Description

In CallAll, once its determined that its not end of a stream, we have the following operations:

  1. Fetch the next item in the stream
  2. Wait for service to be ready
  3. Push the future from .call into the queue.

This can be observed here:

// If not done, and we don't have a stored request, gather the next request from the
// stream (if there is one), or return `Pending` if the stream is not ready.
if this.curr_req.is_none() {
*this.curr_req = match ready!(this.stream.as_mut().poll_next(cx)) {
Some(next_req) => Some(next_req),
None => {
// Mark that there will be no more requests.
*this.eof = true;
continue;
}
};
}
// Then, see that the service is ready for another request
let svc = this
.service
.as_mut()
.expect("Using CallAll after extracting inner Service");
if let Err(e) = ready!(svc.poll_ready(cx)) {
// Set eof to prevent the service from being called again after a `poll_ready` error
*this.eof = true;
return Poll::Ready(Some(Err(e)));
}
// Unwrap: The check above always sets `this.curr_req` if none.
this.queue.push(svc.call(this.curr_req.take().unwrap()));

Motivation

In apalis, we use tower::CallAll to process jobs and in a scenario where someone has a layer blocking service readiness such as ConcurrencyLayer then it means a Request is polled from the Stream then held until the service becomes ready while there might be other consumers that may be available to handle the request.

  • Is it worth considering changing the logic to first check if service is ready then fetch the next item in stream?
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

No branches or pull requests

1 participant