Esempio n. 1
0
  // TODO potential concurrency problem -- late joiner may be added after failure
  public synchronized void addLateJoiner(final CacheRequest request) {

    if (cancelled) {
      request.notifyFailure(RequestFailureType.CANCELLED, null, null, "Cancelled");
      return;
    }

    if (!request.setDownload(this)) {
      notifyAllOnFailure(RequestFailureType.CANCELLED, null, null, "Cancelled");
      return;
    }

    if (request.isJson != initiator.isJson) {
      BugReportActivity.handleGlobalError(
          request.context, "Late joiner disagrees with initiator on JSON type");
      return;
    }

    lateJoiners.add(request);

    if (request.isHigherPriorityThan(highestPriorityReq)) {
      highestPriorityReq = request;
    }

    if (request.isJson) {
      if (value != null)
        request.notifyJsonParseStarted(value, RRTime.utcCurrentTimeMillis(), session, false);
    }
  }
Esempio n. 2
0
  private synchronized void notifyAllDownloadStarted() {

    initiator.notifyDownloadStarted();

    for (final CacheRequest req : lateJoiners) {
      req.notifyDownloadStarted();
    }
  }
Esempio n. 3
0
  private synchronized void notifyAllOnProgress(final long bytesRead, final long bytesTotal) {

    initiator.notifyProgress(bytesRead, bytesTotal);

    for (final CacheRequest req : lateJoiners) {
      req.notifyProgress(bytesRead, bytesTotal);
    }
  }
Esempio n. 4
0
  private synchronized void notifyAllOnJsonParseStarted(
      final JsonValue value, final long timestamp, final UUID session) {

    initiator.notifyJsonParseStarted(value, timestamp, session, false);

    for (final CacheRequest req : lateJoiners) {
      req.notifyJsonParseStarted(value, timestamp, session, false);
    }
  }
Esempio n. 5
0
  private synchronized void notifyAllOnSuccess(
      final CacheManager.ReadableCacheFile cacheFile,
      final long timestamp,
      final UUID session,
      final String mimetype) {

    initiator.notifySuccess(cacheFile, timestamp, session, false, mimetype);

    for (final CacheRequest req : lateJoiners) {
      req.notifySuccess(cacheFile, timestamp, session, false, mimetype);
    }
  }
Esempio n. 6
0
  private synchronized void notifyAllOnFailure(
      final RequestFailureType type,
      final Throwable t,
      final StatusLine status,
      final String readableMessage) {

    initiator.notifyFailure(type, t, status, readableMessage);

    for (final CacheRequest req : lateJoiners) {
      req.notifyFailure(type, t, status, readableMessage);
    }
  }
Esempio n. 7
0
    private void handleRequest(final CacheRequest request) {

      if (request.url == null) {
        request.notifyFailure(
            RequestFailureType.MALFORMED_URL,
            new NullPointerException("URL was null"),
            null,
            "URL was null");
        return;
      }

      switch (request.downloadType) {
        case NEVER:
          {
            final LinkedList<CacheEntry> result =
                dbManager.select(request.url, request.user.username, request.requestSession);

            if (result.size() == 0) {
              request.notifyFailure(
                  RequestFailureType.CACHE_MISS,
                  null,
                  null,
                  "Could not find this data in the cache");

            } else {
              final CacheEntry entry = mostRecentFromList(result);
              handleCacheEntryFound(entry, request);
            }

            break;
          }

        case IF_NECESSARY:
          {
            final LinkedList<CacheEntry> result =
                dbManager.select(request.url, request.user.username, request.requestSession);

            if (result.size() == 0) {
              queueDownload(request);

            } else {
              final CacheEntry entry = mostRecentFromList(result);
              handleCacheEntryFound(entry, request);
            }

            break;
          }

        case FORCE:
          queueDownload(request);
          break;
      }
    }
Esempio n. 8
0
 private Response cacheWritingResponse(CacheRequest cacherequest, Response response)
 {
     ac ac1;
     if (cacherequest != null)
     {
         if ((ac1 = cacherequest.body()) != null)
         {
             cacherequest = new _cls2();
             return response.newBuilder().body(new RealResponseBody(response.headers(), r.a(cacherequest))).build();
         }
     }
     return response;
 }
  public synchronized void add(final CacheRequest request, final CacheManager manager) {

    final RequestIdentifier identifier = request.createIdentifier();

    // Is in progress? If so, add late joiner. or, cancel if requested.

    if (downloadsInProgress.containsKey(identifier)) {
      if (request.cancelExisting) {
        downloadsInProgress.get(identifier).cancel();
      } else {
        downloadsInProgress.get(identifier).addLateJoiner(request);
        return;
      }
    }

    // Is the priority <= 0? If so, spin up a new thread and run immediately.
    if (request.priority <= 0) {

      final CacheDownload download;

      if (downloadsQueued.containsKey(identifier)) {
        download = downloadsQueued.remove(identifier);
        download.addLateJoiner(request);
      } else {
        download = new CacheDownload(request, manager, this);
      }

      downloadsInProgress.put(identifier, download);
      new CacheDownloadThread(this, download, true);

      return;
    }

    // Is in queue? If so, add late joiner

    if (downloadsQueued.containsKey(identifier)) {
      downloadsQueued.get(identifier).addLateJoiner(request);
      return;
    }

    // Otherwise, add to queue and notify all

    downloadsQueued.put(identifier, new CacheDownload(request, manager, this));
    notifyAll();
  }
Esempio n. 10
0
  public CacheDownload(
      final CacheRequest initiator,
      final CacheManager manager,
      final PrioritisedDownloadQueue queue) {

    this.initiator = initiator;

    this.manager = manager;
    this.queue = queue;
    highestPriorityReq = initiator;

    if (!initiator.setDownload(this)) {
      cancel();
    }

    if (initiator.requestSession != null) {
      session = initiator.requestSession;
    } else {
      session = UUID.randomUUID();
    }
  }
Esempio n. 11
0
 public RequestIdentifier createIdentifier() {
   return initiator.createIdentifier();
 }
Esempio n. 12
0
 public synchronized boolean isHigherPriorityThan(final CacheDownload another) {
   return highestPriorityReq.isHigherPriorityThan(another.highestPriorityReq);
 }
Esempio n. 13
0
  private void downloadGet(final HttpClient httpClient) {

    httpGet = new HttpGet(initiator.url);
    if (initiator.isJson) httpGet.setHeader("Accept-Encoding", "gzip");

    final HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(ClientContext.COOKIE_STORE, initiator.getCookies());

    final HttpResponse response;
    final StatusLine status;

    try {
      if (cancelled) {
        notifyAllOnFailure(RequestFailureType.CANCELLED, null, null, "Cancelled");
        return;
      }
      response = httpClient.execute(httpGet, localContext);
      status = response.getStatusLine();

    } catch (Throwable t) {
      t.printStackTrace();
      notifyAllOnFailure(RequestFailureType.CONNECTION, t, null, "Unable to open a connection");
      return;
    }

    if (status.getStatusCode() != 200) {
      notifyAllOnFailure(
          RequestFailureType.REQUEST,
          null,
          status,
          String.format("HTTP error %d (%s)", status.getStatusCode(), status.getReasonPhrase()));
      return;
    }

    if (cancelled) {
      notifyAllOnFailure(RequestFailureType.CANCELLED, null, null, "Cancelled");
      return;
    }

    final HttpEntity entity = response.getEntity();

    if (entity == null) {
      notifyAllOnFailure(
          RequestFailureType.CONNECTION, null, status, "Did not receive a valid HTTP response");
      return;
    }

    final InputStream is;

    try {
      is = entity.getContent();
      mimetype = entity.getContentType() == null ? null : entity.getContentType().getValue();
    } catch (Throwable t) {
      t.printStackTrace();
      notifyAllOnFailure(
          RequestFailureType.CONNECTION, t, status, "Could not open an input stream");
      return;
    }

    final NotifyOutputStream cacheOs;
    if (initiator.cache) {
      try {
        cacheFile = manager.openNewCacheFile(initiator, session, mimetype);
        cacheOs = cacheFile.getOutputStream();
      } catch (IOException e) {
        e.printStackTrace();
        notifyAllOnFailure(RequestFailureType.STORAGE, e, null, "Could not access the local cache");
        return;
      }
    } else {
      cacheOs = null;
    }

    final long contentLength = entity.getContentLength();

    if (initiator.isJson) {

      final InputStream bis;

      if (initiator.cache) {
        final CachingInputStream cis =
            new CachingInputStream(
                is,
                cacheOs,
                new CachingInputStream.BytesReadListener() {
                  public void onBytesRead(final long total) {
                    notifyAllOnProgress(total, contentLength);
                  }
                });

        bis = new BufferedInputStream(cis, 8 * 1024);
      } else {
        bis = new BufferedInputStream(is, 8 * 1024);
      }

      final JsonValue value;

      try {
        value = new JsonValue(bis);
        value.buildInNewThread();

      } catch (Throwable t) {
        t.printStackTrace();
        notifyAllOnFailure(RequestFailureType.PARSE, t, null, "Error parsing the JSON stream");
        return;
      }

      synchronized (this) {
        this.value = value;
        notifyAllOnJsonParseStarted(value, RRTime.utcCurrentTimeMillis(), session);
      }

      try {
        value.join();

      } catch (Throwable t) {
        t.printStackTrace();
        notifyAllOnFailure(RequestFailureType.PARSE, t, null, "Error parsing the JSON stream");
        return;
      }

      success = true;

    } else {

      if (!initiator.cache) {
        BugReportActivity.handleGlobalError(
            initiator.context, "Cache disabled for non-JSON request");
        return;
      }

      try {
        final byte[] buf = new byte[8 * 1024];

        int bytesRead;
        long totalBytesRead = 0;
        while ((bytesRead = is.read(buf)) > 0) {
          totalBytesRead += bytesRead;
          cacheOs.write(buf, 0, bytesRead);
          notifyAllOnProgress(totalBytesRead, contentLength);
        }

        cacheOs.flush();
        cacheOs.close();
        success = true;

      } catch (Throwable t) {
        t.printStackTrace();
        notifyAllOnFailure(
            RequestFailureType.CONNECTION, t, null, "The connection was interrupted");
      }
    }
  }
Esempio n. 14
0
  // TODO merge with downloadGet
  private void downloadPost(final HttpClient httpClient) {

    final HttpPost httpPost = new HttpPost(initiator.url);

    try {
      httpPost.setEntity(new UrlEncodedFormEntity(initiator.postFields, HTTP.UTF_8));
    } catch (UnsupportedEncodingException e) {
      BugReportActivity.handleGlobalError(initiator.context, e);
      return;
    }

    final HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(ClientContext.COOKIE_STORE, initiator.getCookies());

    final HttpResponse response;
    final StatusLine status;

    try {
      response = httpClient.execute(httpPost, localContext);
      status = response.getStatusLine();

    } catch (Throwable t) {
      t.printStackTrace();
      notifyAllOnFailure(RequestFailureType.CONNECTION, t, null, "Unable to open a connection");
      return;
    }

    if (status.getStatusCode() != 200) {
      notifyAllOnFailure(
          RequestFailureType.REQUEST,
          null,
          status,
          String.format("HTTP error %d (%s)", status.getStatusCode(), status.getReasonPhrase()));
      return;
    }

    final HttpEntity entity = response.getEntity();

    if (entity == null) {
      notifyAllOnFailure(
          RequestFailureType.CONNECTION, null, status, "Did not receive a valid HTTP response");
      return;
    }

    final InputStream is;

    try {
      is = entity.getContent();
    } catch (Throwable t) {
      t.printStackTrace();
      notifyAllOnFailure(
          RequestFailureType.CONNECTION, t, status, "Could not open an input stream");
      return;
    }

    if (initiator.isJson) {

      final BufferedInputStream bis = new BufferedInputStream(is, 8 * 1024);

      final JsonValue value;

      try {
        value = new JsonValue(bis);
        value.buildInNewThread();

      } catch (Throwable t) {
        t.printStackTrace();
        notifyAllOnFailure(RequestFailureType.PARSE, t, null, "Error parsing the JSON stream");
        return;
      }

      synchronized (this) {
        this.value = value;
        notifyAllOnJsonParseStarted(value, RRTime.utcCurrentTimeMillis(), session);
      }

      try {
        value.join();

      } catch (Throwable t) {
        t.printStackTrace();
        notifyAllOnFailure(RequestFailureType.PARSE, t, null, "Error parsing the JSON stream");
        return;
      }

      success = true;

    } else {
      throw new RuntimeException("POST requests must be for JSON values");
    }
  }
Esempio n. 15
0
 private void queueDownload(final CacheRequest request) {
   request.notifyDownloadNecessary();
   downloadQueue.add(request, CacheManager.this);
 }