Closed sagebind closed 1 year ago
I'm interested in implementing this.
Is it OK to remove the lifetime directly? We can clone the client everytime we create a response future.
Creating a ResponseFuture
does already require cloning an Arc
, but the scope of what that Arc
contains is too small. We will want to broaden the scope such that only 1 clone is still required.
Internally the function that submits a request to the HTTP agent is called an Invoker
, and the invoker is cloned here in the context whenever an interceptor is involved:
The invoker context is created and placed into an Arc
here:
To make ResponseFuture
static, but without requiring holding onto two Arc
s, we should get rid of the invoker Arc
entirely and refactor the interceptor context to instead pass around the entire HttpClient
. Since one field of a struct cannot borrow values from another, we'll need to change Context
from using slices:
to using indexes to keep track of which interceptor is the current one. That might look something like this:
pub struct Context { // note that Context can now be 'static
pub(crate) client: HttpClient,
pub(crate) interceptor_offset: usize,
}
As a side-effect, this refactoring may actually improve performance, since we won't need to heap-allocate an Invoker
any more on every request.
ResponseFuture
is currently not'static
because it borrows the client instead of doing an implicit clone, but this can be annoying to use with a program structure where you don't pass around the client. This can probably be done without any additional clones or boxing if we do some internal restructuring of the client, which already uses anArc
, such thatResponseFuture
can simply clone the same shared object that cloning anHttpClient
itself does.See also https://github.com/sagebind/isahc/discussions/401.