コード例 #1
0
 public void unsubscribe(USK origUSK, USKCallback cb) {
   USKFetcher toCancel = null;
   synchronized (this) {
     USK clear = origUSK.clearCopy();
     USKCallback[] callbacks = subscribersByClearUSK.get(clear);
     if (callbacks
         == null) { // maybe we should throw something ? shall we allow multiple unsubscriptions ?
       if (logMINOR) Logger.minor(this, "No longer subscribed");
       return;
     }
     int j = 0;
     for (USKCallback c : callbacks) {
       if ((c != null) && (c != cb)) {
         callbacks[j++] = c;
       }
     }
     USKCallback[] newCallbacks = Arrays.copyOf(callbacks, j);
     if (newCallbacks.length > 0) subscribersByClearUSK.put(clear, newCallbacks);
     else {
       subscribersByClearUSK.remove(clear);
     }
     USKFetcher f = backgroundFetchersByClearUSK.get(clear);
     if (f != null) {
       f.removeSubscriber(cb, context);
       if (!f.hasSubscribers()) {
         toCancel = f;
         backgroundFetchersByClearUSK.remove(clear);
       }
     }
     // Temporary background fetchers run once and then die.
     // They do not care about callbacks.
   }
   if (toCancel != null) {
     toCancel.cancel(null, context);
   } else {
     if (logMINOR) Logger.minor(this, "Not found unsubscribing: " + cb + " for " + origUSK);
   }
 }
コード例 #2
0
  public void startTemporaryBackgroundFetcher(
      USK usk,
      ClientContext context,
      final FetchContext fctx,
      boolean prefetchContent,
      boolean realTimeFlag) {
    final USK clear = usk.clearCopy();
    USKFetcher sched = null;
    ArrayList<USKFetcher> toCancel = null;
    synchronized (this) {
      //			int x = 0;
      //			for(USK key: backgroundFetchersByClearUSK.keySet()) {
      //				System.err.println("Fetcher "+x+": "+key);
      //				x++;
      //			}
      USKFetcher f = temporaryBackgroundFetchersLRU.get(clear);
      if (f == null) {
        f =
            new USKFetcher(
                usk,
                this,
                fctx.ignoreUSKDatehints ? backgroundFetchContextIgnoreDBR : backgroundFetchContext,
                new USKFetcherWrapper(
                    usk, RequestStarter.UPDATE_PRIORITY_CLASS, realTimeFlag ? rcRT : rcBulk),
                3,
                false,
                false,
                false);
        sched = f;
        temporaryBackgroundFetchersLRU.push(clear, f);
      } else {
        f.addHintEdition(usk.suggestedEdition);
      }
      if (prefetchContent) {
        long fetchTime = -1;
        // If nothing in 60 seconds, try fetching the last known slot.
        long slot = lookupLatestSlot(clear);
        long good = lookupKnownGood(clear);
        if (slot > -1 && good != slot) fetchTime = System.currentTimeMillis();
        temporaryBackgroundFetchersPrefetch.put(clear, fetchTime);
        if (logMINOR) Logger.minor(this, "Prefetch: set " + fetchTime + " for " + clear);
        schedulePrefetchChecker();
      }
      temporaryBackgroundFetchersLRU.push(clear, f);
      while (temporaryBackgroundFetchersLRU.size() > NodeClientCore.getMaxBackgroundUSKFetchers()) {
        USKFetcher fetcher = temporaryBackgroundFetchersLRU.popValue();
        temporaryBackgroundFetchersPrefetch.remove(fetcher.getOriginalUSK().clearCopy());
        if (!fetcher.hasSubscribers()) {
          if (toCancel == null) toCancel = new ArrayList<USKFetcher>(2);
          toCancel.add(fetcher);
        } else {
          if (logMINOR)
            Logger.minor(
                this,
                "Allowing temporary background fetcher to continue as it has subscribers... "
                    + fetcher);
        }
      }
    }
    final ArrayList<USKFetcher> cancelled = toCancel;
    final USKFetcher scheduleMe = sched;
    // This is just a prefetching method. so it should not unnecessarily delay the parent, nor
    // should it take important locks.
    // So we should do the actual schedule/cancels off-thread.
    // However, the above is done on-thread because a lot of the time it will already be running.
    if (cancelled != null || sched != null) {
      executor.execute(
          new Runnable() {

            @Override
            public void run() {
              if (cancelled != null) {
                for (int i = 0; i < cancelled.size(); i++) {
                  USKFetcher fetcher = cancelled.get(i);
                  fetcher.cancel(null, USKManager.this.context);
                }
              }
              if (scheduleMe != null) scheduleMe.schedule(null, USKManager.this.context);
            }
          });
    }
  }