private void doHttpMaxFailover() {
   long maxTimeAgo = clock.now() - silentPeriodForMaxHttpRequest;
   if (!httpRequestControl.requestQueued(HttpRequestControl.RequestReason.MAX)
       && UpdateSettings.LAST_SIMPP_FAILOVER.getValue() < maxTimeAgo) {
     int rndDelay = RANDOM.nextInt(maxMaxHttpRequestDelay) + minMaxHttpRequestDelay;
     final String rndUri = maxedUpdateList.get(RANDOM.nextInt(maxedUpdateList.size()));
     LOG.debug("Scheduling http max failover in: " + rndDelay + ", to: " + rndUri);
     backgroundExecutor.schedule(
         new Runnable() {
           public void run() {
             String url = rndUri;
             try {
               launchHTTPUpdate(url);
             } catch (URISyntaxException e) {
               httpRequestControl.requestFinished();
               httpRequestControl.cancelRequest();
               LOG.warn("uri failure", e);
             }
           }
         },
         rndDelay,
         TimeUnit.MILLISECONDS);
   } else {
     LOG.debug("Ignoring http max failover.");
   }
 }
    public boolean requestFailed(HttpUriRequest request, HttpResponse response, IOException exc) {
      LOG.warn("http failover failed", exc);
      httpRequestControl.requestFinished();
      UpdateSettings.LAST_SIMPP_FAILOVER.setValue(clock.now());

      httpExecutor.get().releaseResources(response);
      // nothing we can do.
      return false;
    }
    public boolean requestComplete(HttpUriRequest request, HttpResponse response) {
      LOG.debug("http request method succeeded");

      // remember we made an attempt even if it didn't succeed
      UpdateSettings.LAST_SIMPP_FAILOVER.setValue(clock.now());
      final byte[] inflated;
      try {
        if (response.getStatusLine().getStatusCode() < 200
            || response.getStatusLine().getStatusCode() >= 300)
          throw new IOException("bad code " + response.getStatusLine().getStatusCode());

        byte[] resp = null;
        if (response.getEntity() != null) {
          resp = IOUtils.readFully(response.getEntity().getContent());
        }
        if (resp == null || resp.length == 0) throw new IOException("bad body");

        // inflate the response and process.
        inflated = IOUtils.inflate(resp);
      } catch (IOException failed) {
        httpRequestControl.requestFinished();
        LOG.warn("couldn't fetch data ", failed);
        return false;
      } finally {
        httpExecutor.get().releaseResources(response);
      }

      // Handle the data in the background thread.
      backgroundExecutor.execute(
          new Runnable() {
            public void run() {
              httpRequestControl.requestFinished();

              LOG.trace("Parsing new data...");
              handleDataInternal(inflated, UpdateType.FROM_HTTP, null);
            }
          });

      return false; // no more requests
    }