Thank you for your kind reply Oleg.

Based on the Apache Http Client site, it seems that HttpClient 5.0 is
still in beta. What is a good way for me and/or my company to
contribute towards moving the project forward? I'm sure this is
written down somewhere, but I haven't found it.

Thank you,
Elijah

On Tue, Feb 12, 2019 at 1:42 AM Oleg Kalnichevski <ol...@apache.org> wrote:
>
> On Mon, 2019-02-11 at 20:02 -0800, Elijah Zupancic wrote:
> > ====Summary====
> >
> > There is no provision for handling the rfc2616 Retry-After header in
> > the ServiceUnavailableRetryStrategy or ConnectionBackoffStrategy
> > interfaces. This makes implementing a wait based on a response after
> > the server returns a 503 difficult.
> >
> > ====Long Form====
> >
> > Hi Folks,
> >
> > I've been a user of HTTP Client for years and I want to thank all of
> > the developers for their hard work. This is a high quality project
> > and
> > I'm sure it requires a lot of work handling community engagement.
> >
> > I'm using HTTP Client to interface with an open source object store
> > called Manta (https://github.com/joyent/manta) via the Java SDK (also
> > open source: https://github.com/joyent/java-manta). Some users of
> > this
> > object store are sending large amounts of data into the object store
> > and pushing it to its limits. As a result the object store will
> > periodically return 503 Service Unavailable errors with a Retry-After
> > header that provides a hint to the client regarding how many seconds
> > to wait until it retries.
> >
> > When examining the
> > org.apache.http.client.ServiceUnavailableRetryStrategy, I see that
> > the
> > interface contract doesn't make a provision for getting at the
> > Retry-After header (see:
> > https://tools.ietf.org/html/rfc2616#section-14.37) because the
> > getRetryInterval() method doesn't take a HttpResponse parameter.
> >
> > As I understand the design, implementations of the
> > ServiceUnavailableRetryStrategy interface need to be thread-safe, so
> > storing the retry interface as parsed from the HTTP response header
> > when the retryRequest call is invoked, isn't really viable. I could
> > imagine a complex system using ThreadLocal instances to pull this
> > off,
> > but that is far from ideal.
> >
> > Looking at
> > org.apache.http.impl.execchain.ServiceUnavailableRetryExec:88:
> >
> > if (this.retryStrategy.retryRequest(response, c, context)
> >         && RequestEntityProxy.isRepeatable(request)) {
> >     response.close();
> >     final long nextInterval = this.retryStrategy.getRetryInterval();
> >     if (nextInterval > 0) {
> >         try {
> >             this.log.trace("Wait for " + nextInterval);
> >             Thread.sleep(nextInterval);
> >         } catch (final InterruptedException e) {
> >             Thread.currentThread().interrupt();
> >             throw new InterruptedIOException();
> >         }
> >     }
> >
> > One alternative approach, I considered was doing the Thread.sleep()
> > call within the retryRequest() call, but I see that every response is
> > filtered through this code path when a
> > ServiceUnavailableRetryStrategy
> > is assigned and this feels like an abuse of the API contract.
> > Additionally, RequestEntityProxy.isRepeatable() is scoped within the
> > default package scope, so I can't reuse that code path to see if the
> > request is repeatable and I would have to resort to reflection to
> > accomplish the same thing.
> >
> > I also took a look at the
> > org.apache.http.client.ConnectionBackoffStrategy class, but it makes
> > no provision for the total time to backoff but rather adjusts the
> > size
> > of the connection pool (at least that is my understanding).
> >
> > I've been wracking my brain trying to come up with a solution that
> > will preserve API compatibility, but honestly it is hard to do
> > without
> > introducing a wart into the design.
> >
> > One of the less bad options, I considered was adding a method to the
> > ServiceUnavailableRetryStrategy interface:
> >
> > /**
> >  * @param response the response from the target server
> >  * @return The interval between the subsequent auto-retries.
> >  */
> > long getRetryInterval(HttpResponse response);
> >
> > And modify the previously mentioned block as so:
> >
> > if (this.retryStrategy.retryRequest(response, c, context)
> >         && RequestEntityProxy.isRepeatable(request)) {
> >     response.close();
> >     final long nextInterval = this.retryStrategy.getRetryInterval() >
> > 0 ?
> >        this.retryStrategy.getRetryInterval() :
> > this.retryStrategy.getRetryInterval(response);
> >     if (nextInterval > 0) {
> >         try {
> >             this.log.trace("Wait for " + nextInterval);
> >             Thread.sleep(nextInterval);
> >         } catch (final InterruptedException e) {
> >             Thread.currentThread().interrupt();
> >             throw new InterruptedIOException();
> >         }
> >     }
> >
> > This implementation would require careful documentation in the
> > interface.
> >
> > If anyone else has alternative suggestions or feedback, I'm eager and
> > willing to contribute to the project.
> >
> > Thank you,
> > Elijah
> >
>
> Hi Elijah
>
> Support for `Retry-After` was added to HttpClient 5.0 some while ago.
>
> https://github.com/ok2c/httpclient/commit/d5c520a8e1231ae60142158781f5c9bf978fd8e9
>
> There is no elegant way of back-porting it to HttpClient 4.5 other then
> deprecating ServiceUnavailableRetryStrategy interface and replacing it
> with some other interface.
>
> It would probably be better to switch to HttpClient 5.0 instead.
>
> Oleg
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
> For additional commands, e-mail: dev-h...@hc.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to