@Override public List<PersistentChosenBlock> makeBlocks( PersistentChosenRequest request, RequestScheduler sched, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(segment, 1); container.activate(blockNums, 1); } Integer[] blockNumbers; synchronized (this) { blockNumbers = blockNums.toArray(new Integer[blockNums.size()]); } ArrayList<PersistentChosenBlock> blocks = new ArrayList<PersistentChosenBlock>(); Arrays.sort(blockNumbers); int prevBlockNumber = -1; for (int i = 0; i < blockNumbers.length; i++) { int blockNumber = blockNumbers[i]; if (blockNumber == prevBlockNumber) { Logger.error( this, "Duplicate block number in makeBlocks() in " + this + ": two copies of " + blockNumber); continue; } prevBlockNumber = blockNumber; ClientKey key = segment.getBlockKey(blockNumber, container); if (key == null) { if (logMINOR) Logger.minor(this, "Block " + blockNumber + " is null, maybe race condition"); continue; } key = key.cloneKey(); Key k = key.getNodeKey(true); PersistentChosenBlock block = new PersistentChosenBlock( false, request, new MySendableRequestItem(blockNumber), k, key, sched); if (logMINOR) Logger.minor( this, "Created block " + block + " for block number " + blockNumber + " on " + this); blocks.add(block); } blocks.trimToSize(); if (persistent) { container.deactivate(segment, 1); container.deactivate(blockNums, 1); } return blocks; }
@Override public SendableRequestItem chooseKey( KeysFetchingLocally fetching, ObjectContainer container, ClientContext context) { if (persistent) container.activate(key, 5); Key k = key.getNodeKey(false); if (fetching.hasKey(k, this, persistent, container)) return null; long l = fetching.checkRecentlyFailed(k, realTimeFlag); long now = System.currentTimeMillis(); if (l > 0 && l > now) { if (maxRetries == -1 || (maxRetries >= RequestScheduler.COOLDOWN_RETRIES)) { // FIXME synchronization!!! if (logMINOR) Logger.minor( this, "RecentlyFailed -> cooldown until " + TimeUtil.formatTime(l - now) + " on " + this); MyCooldownTrackerItem tracker = makeCooldownTrackerItem(container, context); tracker.cooldownWakeupTime = Math.max(tracker.cooldownWakeupTime, l); return null; } else { this.onFailure( new LowLevelGetException(LowLevelGetException.RECENTLY_FAILED), null, container, context); return null; } } return keys[0]; }
@Override public void removeFrom(ObjectContainer container, ClientContext context) { super.removeFrom(container, context); if (deleteFetchContext) { container.activate(ctx, 1); ctx.removeFrom(container); } container.activate(key, 5); key.removeFrom(container); }
protected void onEncode(ClientKey key, ObjectContainer container, ClientContext context) { synchronized (this) { if (finished) return; if (resultingURI != null) return; resultingURI = key.getURI(); } if (persistent) { container.store(this); container.activate(cb, 1); } cb.onEncode(key, this, container, context); if (persistent) container.deactivate(cb, 1); }
@Override public KeyListener makeKeyListener( ObjectContainer container, ClientContext context, boolean onStartup) { if (persistent) { container.activate(key, 5); container.activate(parent, 1); container.activate(ctx, 1); } synchronized (this) { if (finished) return null; if (cancelled) return null; } if (key == null) { Logger.error( this, "Key is null - left over BSSF? on " + this + " in makeKeyListener()", new Exception("error")); if (persistent) container.delete(this); return null; } Key newKey = key.getNodeKey(true); if (parent == null) { Logger.error( this, "Parent is null on " + this + " persistent=" + persistent + " key=" + key + " ctx=" + ctx); if (container != null) Logger.error( this, "Stored = " + container.ext().isStored(this) + " active = " + container.ext().isActive(this)); return null; } short prio = parent.getPriorityClass(); KeyListener ret = new SingleKeyListener(newKey, this, prio, persistent, realTimeFlag); if (persistent) { container.deactivate(key, 5); container.deactivate(parent, 1); container.deactivate(ctx, 1); } return ret; }
@Override public List<PersistentChosenBlock> makeBlocks( PersistentChosenRequest request, RequestScheduler sched, KeysFetchingLocally keysFetching, ObjectContainer container, ClientContext context) { if (persistent) container.activate(key, 5); ClientKey ckey = key.cloneKey(); Key k = ckey.getNodeKey(true); if (keysFetching.hasKey(k, this, persistent, container)) return null; long l = keysFetching.checkRecentlyFailed(k, realTimeFlag); long now = System.currentTimeMillis(); if (l > 0 && l > now) { if (maxRetries == -1 || (maxRetries >= RequestScheduler.COOLDOWN_RETRIES)) { // FIXME synchronization!!! if (logMINOR) Logger.minor( this, "RecentlyFailed -> cooldown until " + TimeUtil.formatTime(l - now) + " on " + this); MyCooldownTrackerItem tracker = makeCooldownTrackerItem(container, context); tracker.cooldownWakeupTime = Math.max(tracker.cooldownWakeupTime, l); return null; } else { this.onFailure( new LowLevelGetException(LowLevelGetException.RECENTLY_FAILED), null, container, context); return null; } } PersistentChosenBlock block = new PersistentChosenBlock(false, request, keys[0], k, ckey, sched); return Collections.singletonList(block); }
@Override public Key[] listKeys(ObjectContainer container) { if (container != null && !persistent) Logger.error( this, "listKeys() on " + this + " but persistent=false, stored is " + container.ext().isStored(this) + " active is " + container.ext().isActive(this)); synchronized (this) { if (cancelled || finished) return new Key[0]; } if (persistent) container.activate(key, 5); return new Key[] {key.getNodeKey(true)}; }