Strategies for (re)using HTTP client
Hi, I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution. But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request. So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server. What are the recommended approaches here? Esteban A. Maringolo
Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones). A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem. Error handling and recovery are also harder in the reuse case (what state is the connection in ?). ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH, Sven
Thank you Sven. I'll go with instantiating a new client for each request, the less state shared, the better :-) Regards! Esteban A. Maringolo On Fri, Oct 29, 2021 at 12:15 PM Sven Van Caekenberghe <sven@stfx.eu> wrote:
Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones).
A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem.
Error handling and recovery are also harder in the reuse case (what state is the connection in ?).
ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH,
Sven
If I need to use cookies, would it make sense to keep a ZnUserAgentSession and assign it to each new client? I'm asking this in case I have to share cookies between requests. But the session variable seems to be private in ZnClient given that it doesn't provide any setter. Regards, Esteban A. Maringolo On Mon, Nov 1, 2021 at 1:39 PM Esteban Maringolo <emaringolo@gmail.com> wrote:
Thank you Sven.
I'll go with instantiating a new client for each request, the less state shared, the better :-)
Regards!
Esteban A. Maringolo
On Fri, Oct 29, 2021 at 12:15 PM Sven Van Caekenberghe <sven@stfx.eu> wrote:
Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones).
A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem.
Error handling and recovery are also harder in the reuse case (what state is the connection in ?).
ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH,
Sven
On 1 Nov 2021, at 20:03, Esteban Maringolo <emaringolo@gmail.com> wrote:
If I need to use cookies, would it make sense to keep a ZnUserAgentSession and assign it to each new client?
I don't know or remember, my first reaction would be to say that it was not designed for that purpose, but maybe it could be used for that.
I'm asking this in case I have to share cookies between requests. But the session variable seems to be private in ZnClient given that it doesn't provide any setter.
There is the cookie jar object inside the session, maybe you can try to share that ? Or you could copy the necessary cookies over ? That certainly seems like the safest thing.
Regards,
Esteban A. Maringolo
On Mon, Nov 1, 2021 at 1:39 PM Esteban Maringolo <emaringolo@gmail.com> wrote: Thank you Sven.
I'll go with instantiating a new client for each request, the less state shared, the better :-)
Regards!
Esteban A. Maringolo
On Fri, Oct 29, 2021 at 12:15 PM Sven Van Caekenberghe <sven@stfx.eu> wrote: Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones).
A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem.
Error handling and recovery are also harder in the reuse case (what state is the connection in ?).
ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH,
Sven
Maybe this helps: https://github.com/svenvc/zinc/commit/d9fe41707b16748b9340540127ec5d77800856...
On 1 Nov 2021, at 21:22, Sven Van Caekenberghe <sven@stfx.eu> wrote:
On 1 Nov 2021, at 20:03, Esteban Maringolo <emaringolo@gmail.com> wrote:
If I need to use cookies, would it make sense to keep a ZnUserAgentSession and assign it to each new client?
I don't know or remember, my first reaction would be to say that it was not designed for that purpose, but maybe it could be used for that.
I'm asking this in case I have to share cookies between requests. But the session variable seems to be private in ZnClient given that it doesn't provide any setter.
There is the cookie jar object inside the session, maybe you can try to share that ?
Or you could copy the necessary cookies over ? That certainly seems like the safest thing.
Regards,
Esteban A. Maringolo
On Mon, Nov 1, 2021 at 1:39 PM Esteban Maringolo <emaringolo@gmail.com> wrote: Thank you Sven.
I'll go with instantiating a new client for each request, the less state shared, the better :-)
Regards!
Esteban A. Maringolo
On Fri, Oct 29, 2021 at 12:15 PM Sven Van Caekenberghe <sven@stfx.eu> wrote: Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones).
A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem.
Error handling and recovery are also harder in the reuse case (what state is the connection in ?).
ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH,
Sven
Thanks Sven! I don't know whether I'm going to use it, but it's good that the feature is there and I have the option of sharing such session among clients. Regards, Esteban A. Maringolo On Wed, Nov 3, 2021 at 1:06 PM Sven Van Caekenberghe <sven@stfx.eu> wrote:
Maybe this helps:
https://github.com/svenvc/zinc/commit/d9fe41707b16748b9340540127ec5d77800856...
On 1 Nov 2021, at 21:22, Sven Van Caekenberghe <sven@stfx.eu> wrote:
On 1 Nov 2021, at 20:03, Esteban Maringolo <emaringolo@gmail.com> wrote:
If I need to use cookies, would it make sense to keep a ZnUserAgentSession and assign it to each new client?
I don't know or remember, my first reaction would be to say that it was not designed for that purpose, but maybe it could be used for that.
I'm asking this in case I have to share cookies between requests. But the session variable seems to be private in ZnClient given that it doesn't provide any setter.
There is the cookie jar object inside the session, maybe you can try to share that ?
Or you could copy the necessary cookies over ? That certainly seems like the safest thing.
Regards,
Esteban A. Maringolo
On Mon, Nov 1, 2021 at 1:39 PM Esteban Maringolo <emaringolo@gmail.com> wrote: Thank you Sven.
I'll go with instantiating a new client for each request, the less state shared, the better :-)
Regards!
Esteban A. Maringolo
On Fri, Oct 29, 2021 at 12:15 PM Sven Van Caekenberghe <sven@stfx.eu> wrote: Hi,
On 29 Oct 2021, at 15:42, Esteban Maringolo <emaringolo@gmail.com> wrote:
Hi,
I happened to me more than once that I have to create some REST service "client" in which I usually wrap an HTTP client inside (ZnClient in this case), and all the calls to the service, end up using the HTTP client, inside some mutex to serialize the execution.
Yes, that is a good design. However, whether your REST client object wrapping a ZnClient is used by multiple concurrent threads is another decision. I would personally not do that. See further.
But I don't like that, in particular when some endpoints are better with streaming responses (large downloads) and I have to fiddle with the client and set it back to the settings before executing the request.
You only can and should reuse connections to the same endpoint/service only, doing similar types of request/responses (let's say simple ones).
A definitive danger point is authentication and authorization: different calls by different users might need different REST call settings, each time. Also, caching can be a problem, if user A can see / sees the cache of user B.
So, long story short... is it always safer to instantiate a new ZnClient on a per request basis since no state is shared, but I guess it is also less effective if I'm performing several requests to the same server.
A new instance is definitely safer because it is cleaner. Reusing a connection is more efficient when doing multiple calls in (quick) succession. The penalty is usually pretty low, you can postpone optimising until there is an actual problem.
Error handling and recovery are also harder in the reuse case (what state is the connection in ?).
ZnClient does a form of automatic reconnection/retry though.
What are the recommended approaches here?
Esteban A. Maringolo
HTH,
Sven
participants (2)
-
Esteban Maringolo -
Sven Van Caekenberghe