You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Dan Checkoway <dc...@gmail.com> on 2011/06/23 11:45:56 UTC

how to automatically retry after 503 Service Unavailable

I'm doing this:

httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(2,
true));
...
return httpClient.execute(new HttpGet(url), jsonResponseHandler, new
BasicHttpContext());

...but when the server returns "503 Service Unavailable" I don't believe the
retry handler is getting invoked.  My response handler looks like:

    private static final class JsonResponseHandler implements
ResponseHandler<Map> {
        public Map handleResponse(HttpResponse httpResponse) throws
java.io.IOException {
            HttpEntity httpEntity = httpResponse.getEntity();
            try {
                StatusLine statusLine = httpResponse.getStatusLine();
                switch (statusLine.getStatusCode()) {
                case 200: // Should be a valid JSON response
                    return (Map)JSONValue.parseWithException(new
InputStreamReader(httpEntity.getContent()));
                case 503:
                default:
                    throw new
HttpResponseException(statusLine.getStatusCode(), statusLine.toString());
                }
                ...

I'm not 100% sure if throwing that HttpResponseException is causing the
retry to get invoked, but I don't think it is.  Is there anything else I
should be doing in that "case 503:" that would induce a retry automatically?

Or do I need to wrap my own retry logic around the httpClient.execute call?
I'm sure I'm missing something simple.

Dan

Re: how to automatically retry after 503 Service Unavailable

Posted by Dan Checkoway <dc...@gmail.com>.
Thanks for the reply, Oleg.  I appreciate it.  If anybody out there has
rolled their own wrapper around an HttpClient, shoot it my way...otherwise
I'll contrib mine here when it's done.  I picture something like:

HttpStatusBasedRetryWrapper wrapper = new
HttpStatusBasedRetryWrapper(httpClient);
wrapper.getRetryOnStatuses().add(503);
wrapper.setRetryCount(n);
wrapper.execute(...);

...or something like that.  It's kind of a shame that the
HttpRequestRetryHandler can't be used (or reused, I should say) like that.
i.e. one mode of retry check determines if a retry can be performed
following an IOException, and the other mode of retry check determines if a
retry can be performed up receiving a non-200.  Basically what I'm saying is
that I'd like to encapsulate my complete "business logic" for when retries
are acceptable into a single class.  Suppose I can still do that, just needs
to be invoked from two places.

If I'm reinventing the wheel, let me know, otherwise I'll carry on...  :-)

Thanks,
Dan

On Thu, Jun 23, 2011 at 6:58 AM, Oleg Kalnichevski <ol...@apache.org> wrote:

> On Thu, 2011-06-23 at 05:53 -0400, Dan Checkoway wrote:
> > BTW, I looked at the HttpClient code, and I see that in
> > AbstractHttpClient.execute, the call to director.execute has finished
> > completely before my ResponseHandler gets called.  In other words, the
> > chance for the retryHandler to kick in is already long gone by the time I
> > see the 503 in my ResponseHandler.
> >
> > So I guess to refine my last question...is there an uber simple way to
> > induce a retry in the scenario where my ResponseHandler bumps into a 503?
> > Seems like I'm going to have to throw some specific exception up to my
> code
> > that's calling httpClient.execute, and handle it there...but is there an
> > out-of-the-box way to handle it?
> >
> > Dan
> >
>
> Dan
>
> HttpClient cannot make assumptions as to whether or not a request is
> safe to retry based on a status code. If 503 status indicates a
> recoverable error in your application's context you will have to
> implement a custom recovery mechanism to handle it.
>
> Hope this helps
>
> Oleg
>
> >
> > On Thu, Jun 23, 2011 at 5:45 AM, Dan Checkoway <dc...@gmail.com>
> wrote:
> >
> > > I'm doing this:
> > >
> > > httpClient.setHttpRequestRetryHandler(new
> DefaultHttpRequestRetryHandler(2,
> > > true));
> > > ...
> > > return httpClient.execute(new HttpGet(url), jsonResponseHandler, new
> > > BasicHttpContext());
> > >
> > > ...but when the server returns "503 Service Unavailable" I don't
> believe
> > > the retry handler is getting invoked.  My response handler looks like:
> > >
> > >     private static final class JsonResponseHandler implements
> > > ResponseHandler<Map> {
> > >         public Map handleResponse(HttpResponse httpResponse) throws
> > > java.io.IOException {
> > >             HttpEntity httpEntity = httpResponse.getEntity();
> > >             try {
> > >                 StatusLine statusLine = httpResponse.getStatusLine();
> > >                 switch (statusLine.getStatusCode()) {
> > >                 case 200: // Should be a valid JSON response
> > >                     return (Map)JSONValue.parseWithException(new
> > > InputStreamReader(httpEntity.getContent()));
> > >                 case 503:
> > >                 default:
> > >                     throw new
> > > HttpResponseException(statusLine.getStatusCode(),
> statusLine.toString());
> > >                 }
> > >                 ...
> > >
> > > I'm not 100% sure if throwing that HttpResponseException is causing the
> > > retry to get invoked, but I don't think it is.  Is there anything else
> I
> > > should be doing in that "case 503:" that would induce a retry
> automatically?
> > >
> > > Or do I need to wrap my own retry logic around the httpClient.execute
> > > call?  I'm sure I'm missing something simple.
> > >
> > > Dan
> > >
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

Re: how to automatically retry after 503 Service Unavailable

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Thu, 2011-06-23 at 05:53 -0400, Dan Checkoway wrote:
> BTW, I looked at the HttpClient code, and I see that in
> AbstractHttpClient.execute, the call to director.execute has finished
> completely before my ResponseHandler gets called.  In other words, the
> chance for the retryHandler to kick in is already long gone by the time I
> see the 503 in my ResponseHandler.
> 
> So I guess to refine my last question...is there an uber simple way to
> induce a retry in the scenario where my ResponseHandler bumps into a 503?
> Seems like I'm going to have to throw some specific exception up to my code
> that's calling httpClient.execute, and handle it there...but is there an
> out-of-the-box way to handle it?
> 
> Dan
> 

Dan

HttpClient cannot make assumptions as to whether or not a request is
safe to retry based on a status code. If 503 status indicates a
recoverable error in your application's context you will have to
implement a custom recovery mechanism to handle it.

Hope this helps

Oleg

> 
> On Thu, Jun 23, 2011 at 5:45 AM, Dan Checkoway <dc...@gmail.com> wrote:
> 
> > I'm doing this:
> >
> > httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(2,
> > true));
> > ...
> > return httpClient.execute(new HttpGet(url), jsonResponseHandler, new
> > BasicHttpContext());
> >
> > ...but when the server returns "503 Service Unavailable" I don't believe
> > the retry handler is getting invoked.  My response handler looks like:
> >
> >     private static final class JsonResponseHandler implements
> > ResponseHandler<Map> {
> >         public Map handleResponse(HttpResponse httpResponse) throws
> > java.io.IOException {
> >             HttpEntity httpEntity = httpResponse.getEntity();
> >             try {
> >                 StatusLine statusLine = httpResponse.getStatusLine();
> >                 switch (statusLine.getStatusCode()) {
> >                 case 200: // Should be a valid JSON response
> >                     return (Map)JSONValue.parseWithException(new
> > InputStreamReader(httpEntity.getContent()));
> >                 case 503:
> >                 default:
> >                     throw new
> > HttpResponseException(statusLine.getStatusCode(), statusLine.toString());
> >                 }
> >                 ...
> >
> > I'm not 100% sure if throwing that HttpResponseException is causing the
> > retry to get invoked, but I don't think it is.  Is there anything else I
> > should be doing in that "case 503:" that would induce a retry automatically?
> >
> > Or do I need to wrap my own retry logic around the httpClient.execute
> > call?  I'm sure I'm missing something simple.
> >
> > Dan
> >



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Re: how to automatically retry after 503 Service Unavailable

Posted by Dan Checkoway <dc...@gmail.com>.
BTW, I looked at the HttpClient code, and I see that in
AbstractHttpClient.execute, the call to director.execute has finished
completely before my ResponseHandler gets called.  In other words, the
chance for the retryHandler to kick in is already long gone by the time I
see the 503 in my ResponseHandler.

So I guess to refine my last question...is there an uber simple way to
induce a retry in the scenario where my ResponseHandler bumps into a 503?
Seems like I'm going to have to throw some specific exception up to my code
that's calling httpClient.execute, and handle it there...but is there an
out-of-the-box way to handle it?

Dan


On Thu, Jun 23, 2011 at 5:45 AM, Dan Checkoway <dc...@gmail.com> wrote:

> I'm doing this:
>
> httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(2,
> true));
> ...
> return httpClient.execute(new HttpGet(url), jsonResponseHandler, new
> BasicHttpContext());
>
> ...but when the server returns "503 Service Unavailable" I don't believe
> the retry handler is getting invoked.  My response handler looks like:
>
>     private static final class JsonResponseHandler implements
> ResponseHandler<Map> {
>         public Map handleResponse(HttpResponse httpResponse) throws
> java.io.IOException {
>             HttpEntity httpEntity = httpResponse.getEntity();
>             try {
>                 StatusLine statusLine = httpResponse.getStatusLine();
>                 switch (statusLine.getStatusCode()) {
>                 case 200: // Should be a valid JSON response
>                     return (Map)JSONValue.parseWithException(new
> InputStreamReader(httpEntity.getContent()));
>                 case 503:
>                 default:
>                     throw new
> HttpResponseException(statusLine.getStatusCode(), statusLine.toString());
>                 }
>                 ...
>
> I'm not 100% sure if throwing that HttpResponseException is causing the
> retry to get invoked, but I don't think it is.  Is there anything else I
> should be doing in that "case 503:" that would induce a retry automatically?
>
> Or do I need to wrap my own retry logic around the httpClient.execute
> call?  I'm sure I'm missing something simple.
>
> Dan
>