private void done(Throwable cause) { PnfsId pnfsId = getFileAttributes().getPnfsId(); if (cause != null) { if (cause instanceof InterruptedException || cause instanceof CancellationException) { cause = new TimeoutCacheException("Flush was cancelled.", cause); } if (cause instanceof CacheException) { infoMsg.setResult(((CacheException) cause).getRc(), cause.getMessage()); } else { infoMsg.setResult(CacheException.DEFAULT_ERROR_CODE, cause.getMessage()); } } infoMsg.setTransferTime(System.currentTimeMillis() - activatedAt); infoMsg.setFileSize(getFileAttributes().getSize()); infoMsg.setTimeQueued(activatedAt - createdAt); if (!suppressedStoreErrors.contains(infoMsg.getResultCode())) { if (infoMsg.getResultCode() != 0) { LOGGER.warn("Flush of {} failed with: {}.", pnfsId, cause.toString()); } billingStub.notify(infoMsg); } flushRequests.removeAndCallback(pnfsId, cause); }
/** Cancels requests whose deadline has past. */ public void cancelExpiredRequests() { long now = System.currentTimeMillis(); for (R request : requests.values()) { if (request.getDeadline() <= now) { request.cancel(); } } }
public ListenableFuture<Void> activate() { if (!state.compareAndSet(State.QUEUED, State.ACTIVE)) { return Futures.immediateFailedFuture( new IllegalStateException("Request is no longer queued.")); } activatedAt = System.currentTimeMillis(); return Futures.immediateFuture(null); }
@PreDestroy public void shutdown() throws InterruptedException { flushRequests.shutdown(); stageRequests.shutdown(); removeRequests.shutdown(); if (timeoutFuture != null) { timeoutFuture.cancel(false); } repository.removeListener(this); /* Waits for all requests to have finished. This is blocking to avoid that the * repository gets closed nearline storage requests have had a chance to finish. */ long deadline = System.currentTimeMillis() + 3000; if (flushRequests.awaitTermination( deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS)) { if (stageRequests.awaitTermination( deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS)) { removeRequests.awaitTermination( deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } } }
private void done(Throwable cause) { PnfsId pnfsId = getFileAttributes().getPnfsId(); if (cause != null) { if (cause instanceof InterruptedException || cause instanceof CancellationException) { cause = new TimeoutCacheException("Stage was cancelled.", cause); } LOGGER.warn("Stage of {} failed with {}.", pnfsId, cause); } descriptor.close(); if (cause instanceof CacheException) { infoMsg.setResult(((CacheException) cause).getRc(), cause.getMessage()); } else if (cause != null) { infoMsg.setResult(CacheException.DEFAULT_ERROR_CODE, cause.toString()); } infoMsg.setTransferTime(System.currentTimeMillis() - activatedAt); billingStub.notify(infoMsg); stageRequests.removeAndCallback(pnfsId, cause); }
/** * Abstract base class for request implementations. * * <p>Provides support for registering callbacks and deregistering from a RequestContainer when * the request has completed. * * <p>Implements part of NearlineRequest, although the interface isn't formally implemented. * Subclasses implement subinterfaces of NearlineRequest. * * @param <K> key identifying a request */ private abstract static class AbstractRequest<K> implements Comparable<AbstractRequest<K>> { protected enum State { QUEUED, ACTIVE, CANCELED } private final List<CompletionHandler<Void, K>> callbacks = new ArrayList<>(); protected final long createdAt = System.currentTimeMillis(); protected final UUID uuid = UUID.randomUUID(); protected final NearlineStorage storage; protected final AtomicReference<State> state = new AtomicReference<>(State.QUEUED); protected volatile long activatedAt; private final List<Future<?>> asyncTasks = new ArrayList<>(); AbstractRequest(NearlineStorage storage) { this.storage = storage; } // Implements NearlineRequest#setIncluded public UUID getId() { return uuid; } public long getCreatedAt() { return createdAt; } protected synchronized <T> ListenableFuture<T> register(ListenableFuture<T> future) { if (state.get() == State.CANCELED) { future.cancel(true); } else { asyncTasks.add(future); } return future; } public ListenableFuture<Void> activate() { if (!state.compareAndSet(State.QUEUED, State.ACTIVE)) { return Futures.immediateFailedFuture( new IllegalStateException("Request is no longer queued.")); } activatedAt = System.currentTimeMillis(); return Futures.immediateFuture(null); } // Guarded by the container containing this request public void addCallback(CompletionHandler<Void, K> callback) { callbacks.add(callback); } // Guarded by the container containing this request public Iterable<CompletionHandler<Void, K>> callbacks() { return this.callbacks; } public void cancel() { if (state.getAndSet(State.CANCELED) != State.CANCELED) { storage.cancel(uuid); synchronized (this) { for (Future<?> task : asyncTasks) { task.cancel(true); } } } } public void failed(int rc, String msg) { failed(CacheExceptionFactory.exceptionOf(rc, msg)); } public abstract void failed(Exception cause); @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(uuid).append(' ').append(state).append(' ').append(new Date(createdAt)); long activatedAt = this.activatedAt; if (activatedAt > 0) { sb.append(' ').append(new Date(activatedAt)); } return sb.toString(); } @Override public int compareTo(AbstractRequest<K> o) { return Longs.compare(createdAt, o.createdAt); } }