public void onFailure( FetchException e, Object token, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(segment, 1); container.activate(parent, 1); container.activate(segment.errors, 1); } boolean forceFatal = false; if (parent.isCancelled()) { if (logMINOR) Logger.minor(this, "Failing: cancelled"); e = new FetchException(FetchException.CANCELLED); forceFatal = true; } segment.errors.inc(e.getMode()); if (persistent) segment.errors.storeTo(container); if (e.isFatal() && token == null) { segment.fail(e, container, context, false); } else if (e.isFatal() || forceFatal) { segment.onFatalFailure( e, ((SplitFileFetcherSegmentSendableRequestItem) token).blockNum, container, context); } else { segment.onNonFatalFailure( e, ((SplitFileFetcherSegmentSendableRequestItem) token).blockNum, container, context); } if (persistent) { container.deactivate(segment, 1); container.deactivate(parent, 1); container.deactivate(segment.errors, 1); } }
// Real onFailure protected void onFailure( FetchException e, Object token, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(segment, 1); container.activate(parent, 1); container.activate(segment.errors, 1); } boolean forceFatal = false; if (parent.isCancelled()) { if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Failing: cancelled"); e = new FetchException(FetchException.CANCELLED); forceFatal = true; } segment.errors.inc(e.getMode()); if (e.isFatal() && token == null) { segment.fail(e, container, context, false); } else if (e.isFatal() || forceFatal) { segment.onFatalFailure(e, ((MySendableRequestItem) token).x, this, container, context); } else { segment.onNonFatalFailure(e, ((MySendableRequestItem) token).x, this, container, context); } removeBlockNum(((MySendableRequestItem) token).x, container, false); if (persistent) { container.deactivate(segment, 1); container.deactivate(parent, 1); container.deactivate(segment.errors, 1); } }
@Override public ClientKey getKey(Object token, ObjectContainer container) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); } synchronized (segment) { if (cancelled) { if (logMINOR) Logger.minor(this, "Segment is finishing when getting key " + token + " on " + this); return null; } ClientKey key = segment.getBlockKey(((MySendableRequestItem) token).x, container); if (key == null) { if (segment.isFinished(container)) { Logger.error(this, "Segment finished but didn't tell us! " + this); } else if (segment.isFinishing(container)) { Logger.error(this, "Segment finishing but didn't tell us! " + this); } else { Logger.error( this, "Segment not finishing yet still returns null for getKey()!: " + token + " for " + this, new Exception("debug")); } } return key; } }
public void onFailure( BulkCallFailureItem[] items, ObjectContainer container, ClientContext context) { FetchException[] fetchExceptions = new FetchException[items.length]; int countFatal = 0; if (persistent) { container.activate(blockNums, 2); } for (int i = 0; i < items.length; i++) { fetchExceptions[i] = translateException(items[i].e); if (fetchExceptions[i].isFatal()) countFatal++; removeBlockNum(((MySendableRequestItem) items[i].token).x, container, true); } if (persistent) { container.store(blockNums); container.deactivate(blockNums, 2); container.activate(segment, 1); container.activate(parent, 1); container.activate(segment.errors, 1); } if (parent.isCancelled()) { if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Failing: cancelled"); // Fail the segment. segment.fail(new FetchException(FetchException.CANCELLED), container, context, false); // FIXME do we need to free the keyNum's??? Or will that happen later anyway? return; } for (int i = 0; i < fetchExceptions.length; i++) segment.errors.inc(fetchExceptions[i].getMode()); int nonFatalExceptions = items.length - countFatal; int[] blockNumbers = new int[nonFatalExceptions]; if (countFatal > 0) { FetchException[] newFetchExceptions = new FetchException[items.length - countFatal]; // Call the fatal callbacks directly. int x = 0; for (int i = 0; i < items.length; i++) { int blockNum = ((MySendableRequestItem) items[i].token).x; if (fetchExceptions[i].isFatal()) { segment.onFatalFailure(fetchExceptions[i], blockNum, this, container, context); } else { blockNumbers[x] = blockNum; newFetchExceptions[x] = fetchExceptions[i]; x++; } } fetchExceptions = newFetchExceptions; } else { for (int i = 0; i < blockNumbers.length; i++) blockNumbers[i] = ((MySendableRequestItem) items[i].token).x; } segment.onNonFatalFailure(fetchExceptions, blockNumbers, this, container, context); if (persistent) { container.deactivate(segment, 1); container.deactivate(parent, 1); container.deactivate(segment.errors, 1); } }
@Override public boolean hasValidKeys( KeysFetchingLocally keys, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(this, 1); container.activate(blockNums, 1); container.activate(segment, 1); } boolean hasSet = false; boolean retval = false; synchronized (segment) { for (int i = 0; i < 10; i++) { Integer ret; int x; if (blockNums.isEmpty()) { break; } x = context.random.nextInt(blockNums.size()); ret = blockNums.get(x); int block = ret; Key key = segment.getBlockNodeKey(block, container); if (key == null) { if (segment.isFinishing(container) || segment.isFinished(container)) return false; if (segment.haveBlock(block, container)) Logger.error( this, "Already have block " + ret + " but was in blockNums on " + this + " in hasValidKeys"); else Logger.error( this, "Key is null for block " + ret + " for " + this + " in hasValidKeys"); blockNums.remove(x); if (persistent) { container.delete(ret); if (!hasSet) { hasSet = true; container.store(blockNums); } } continue; } if (keys.hasKey(key)) { continue; } retval = true; break; } } if (persistent) { container.deactivate(blockNums, 5); container.deactivate(segment, 1); } return retval; }
@Override public long getCooldownWakeup(Object token, ObjectContainer container, ClientContext context) { if (persistent) container.activate(segment, 1); return segment.getCooldownWakeup( ((SplitFileFetcherSegmentSendableRequestItem) token).blockNum, segment.getMaxRetries(container), container, context); }
public void onGotKey(Key key, KeyBlock block, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); container.activate(blockNums, 1); } if (logMINOR) Logger.minor(this, "onGotKey(" + key + ")"); // Find and remove block if it is on this subsegment. However it may have been // removed already. int blockNo; synchronized (segment) { for (int i = 0; i < blockNums.size(); i++) { Integer token = blockNums.get(i); int num = token; Key k = segment.getBlockNodeKey(num, container); if (k != null && k.equals(key)) { blockNums.remove(i); if (persistent) container.delete(token); break; } } blockNo = segment.getBlockNumber(key, container); } if (blockNo == -1) { Logger.minor(this, "No block found for key " + key + " on " + this); return; } Integer token = Integer.valueOf(blockNo); ClientCHK ckey = segment.getBlockKey(blockNo, container); ClientCHKBlock cb; try { cb = new ClientCHKBlock((CHKBlock) block, ckey); } catch (CHKVerifyException e) { onFailure( new FetchException(FetchException.BLOCK_DECODE_ERROR, e), token, container, context); return; } Bucket data = extract(cb, token, container, context); if (data == null) return; if (!cb.isMetadata()) { onSuccess(data, false, token, (token).intValue(), cb, container, context); } else { onFailure( new FetchException(FetchException.INVALID_METADATA, "Metadata where expected data"), token, container, context); } }
@Override public ClientKey getKey(Object token, ObjectContainer container) { SplitFileFetcherSegmentSendableRequestItem req = (SplitFileFetcherSegmentSendableRequestItem) token; if (persistent) container.activate(segment, 1); return segment.getBlockKey(req.blockNum, container); }
private SendableRequestItem getRandomBlockNum( KeysFetchingLocally keys, ClientContext context, ObjectContainer container) { if (persistent) { container.activate(this, 1); container.activate(blockNums, 1); container.activate(segment, 1); } logMINOR = Logger.shouldLog(Logger.MINOR, this); synchronized (segment) { if (blockNums.isEmpty()) { if (logMINOR) Logger.minor(this, "No blocks to remove"); return null; } for (int i = 0; i < 10; i++) { Integer ret; int x; if (blockNums.size() == 0) return null; x = context.random.nextInt(blockNums.size()); ret = blockNums.get(x); int num = ret; Key key = segment.getBlockNodeKey(num, container); if (key == null) { if (segment.isFinishing(container) || segment.isFinished(container)) return null; if (segment.haveBlock(num, container)) Logger.error(this, "Already have block " + ret + " but was in blockNums on " + this); else Logger.error(this, "Key is null for block " + ret + " for " + this); continue; } if (keys.hasKey(key)) { continue; } if (logMINOR) Logger.minor( this, "Removing block " + x + " of " + (blockNums.size() + 1) + " : " + ret + " on " + this); return new MySendableRequestItem(num); } return null; } }
@Override public void requeueAfterCooldown( Key key, long time, ObjectContainer container, ClientContext context) { if (persistent) container.activate(segment, 1); int blockNum = segment.getBlockNumber(key, container); if (blockNum == -1) return; reschedule(container, context); }
@Override public SendableRequestItem chooseKey( KeysFetchingLocally keys, ObjectContainer container, ClientContext context) { if (persistent) container.activate(segment, 1); ArrayList<Integer> possibles = segment.validBlockNumbers(keys, true, container, context); if (possibles == null || possibles.isEmpty()) return null; return new SplitFileFetcherSegmentSendableRequestItem( possibles.get(context.random.nextInt(possibles.size()))); }
@Override public long getCooldownWakeup(Object token, ObjectContainer container) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); } long ret = segment.getCooldownWakeup(((MySendableRequestItem) token).x); return ret; }
public long getCooldownTime(ObjectContainer container, ClientContext context, long now) { if (persistent) container.activate(segment, 1); HasCooldownCacheItem parentRGA = getParentGrabArray(); long wakeTime = segment.getCooldownTime(container, context, parentRGA, now); if (wakeTime > 0) context.cooldownTracker.setCachedWakeup( wakeTime, this, parentRGA, persistent, container, context, true); return wakeTime; }
@Override public void resetCooldownTimes(ObjectContainer container) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); } synchronized (segment) { segment.resetCooldownTimes(blockNums.toArray(new Integer[blockNums.size()])); } }
@Override public Key[] listKeys(ObjectContainer container) { boolean activated = false; if (persistent) { activated = container.ext().isActive(segment); if (!activated) container.activate(segment, 1); } Key[] keys = segment.listKeys(container); if (persistent && !activated) container.deactivate(segment, 1); return keys; }
/** * Fetch the array from the segment because we need to include *ALL* keys, especially those on * cooldown queues. This is important when unregistering. */ @Override public long countAllKeys(ObjectContainer container, ClientContext context) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); } // j16sdiz (22-DEC-2008): // ClientRequestSchedular.removePendingKeys() call this to get a list of request to be removed // FIXME ClientRequestSchedular.removePendingKeys() is leaking, what's missing here? return segment.getKeyNumbersAtRetryLevel(retryCount).length; }
@Override public List<PersistentChosenBlock> makeBlocks( PersistentChosenRequest request, RequestScheduler sched, ObjectContainer container, ClientContext context) { if (persistent) container.activate(segment, 1); // FIXME why is the fetching keys list not passed in? We could at least check for other fetchers // for the same key??? Need to modify the parameters ... List<PersistentChosenBlock> blocks = segment.makeBlocks(request, sched, container, context); if (persistent) container.deactivate(segment, 1); return blocks; }
@Override public long getCooldownWakeupByKey(Key key, ObjectContainer container, ClientContext context) { /* Only deactivate if was deactivated in the first place. * See the removePendingKey() stack trace: Segment is the listener (getter) ! */ boolean activated = false; if (persistent) { activated = container.ext().isActive(segment); if (!activated) container.activate(segment, 1); } long ret = segment.getCooldownWakeupByKey(key, container, context); if (persistent) { if (!activated) container.deactivate(segment, 1); } return ret; }
@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; }
protected void onSuccess( Bucket data, boolean fromStore, Integer token, int blockNo, ClientKeyBlock block, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); container.activate(parent, 1); } if (parent.isCancelled()) { data.free(); if (persistent) data.removeFrom(container); onFailure(new FetchException(FetchException.CANCELLED), token, container, context); return; } segment.onSuccess(data, blockNo, block, container, context, this); }
/** * If there are no more blocks, cancel the SubSegment, remove it from the segment, and return * true; the caller must call kill(,,true,true). Else return false. * * @param container * @param context * @return */ public boolean possiblyRemoveFromParent(ObjectContainer container, ClientContext context) { if (persistent) { container.activate(this, 1); container.activate(segment, 1); container.activate(blockNums, 1); } if (logMINOR) Logger.minor(this, "Possibly removing from parent: " + this); synchronized (segment) { if (!blockNums.isEmpty()) { if (persistent) container.deactivate(blockNums, 1); return false; } if (logMINOR) Logger.minor(this, "Definitely removing from parent: " + this); if (!segment.maybeRemoveSeg(this, container)) { if (persistent) container.deactivate(blockNums, 1); return false; } cancelled = true; } return true; }
@Override public void requeueAfterCooldown( Key key, long time, ObjectContainer container, ClientContext context) { if (persistent) { container.activate(segment, 1); } if (cancelled) { if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Not requeueing as already cancelled"); return; } if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Requeueing after cooldown " + key + " for " + this); if (!segment.requeueAfterCooldown(key, time, container, context, this)) { Logger.error( this, "Key was not wanted after cooldown: " + key + " for " + this + " in requeueAfterCooldown"); } if (persistent) container.deactivate(segment, 1); }
public boolean isEmpty(ObjectContainer container) { if (persistent) container.activate(segment, 1); return segment.isFinishing(container); }
@Override public long countSendableKeys(ObjectContainer container, ClientContext context) { if (persistent) container.activate(segment, 1); return segment.countSendableKeys(container, context); }