ResponseWriter(final Request request, final Response response, final boolean configSetStatusOverSendError) { this.response = response; this.continuation = ContinuationSupport.getContinuation(request); this.configSetStatusOverSendError = configSetStatusOverSendError; }
@Override public void setSuspendTimeout(final long timeOut, final TimeUnit timeUnit) throws IllegalStateException { if (timeOut > 0) { final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit); continuation.setTimeout(timeoutMillis); } }
@Override public boolean suspend(final long timeOut, final TimeUnit timeUnit, final TimeoutHandler timeoutHandler) { try { if (timeOut > 0) { final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit); continuation.setTimeout(timeoutMillis); } continuation.addContinuationListener(new ContinuationListener() { @Override public void onComplete(final Continuation continuation) { } @Override public void onTimeout(final Continuation continuation) { if (timeoutHandler != null) { timeoutHandler.onTimeout(ResponseWriter.this); } } }); continuation.suspend(response); return true; } catch (final Exception ex) { return false; } }
final Continuation cont = ContinuationSupport.getContinuation(httpServletRequest); if (!cont.isResumed() && !queue.messagesWaiting()) { queue.setActivationCallback(new JettyQueueActivationCallback(cont)); cont.setTimeout(30 * 1000); cont.suspend(); if (cont.isResumed()) { return;
@Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { metrics.getRequestsMeter().mark(); if (!target.equals(s3Configuration.getLocalDownloadPath())) { metrics.getClientErrorsMeter().mark(); response.sendError(404); return; } if (!request.getMethod().equalsIgnoreCase(HttpMethod.POST.name())) { metrics.getClientErrorsMeter().mark(); response.sendError(405); return; } Optional<ArtifactDownloadRequest> artifactOptional = readDownloadRequest(request); if (!artifactOptional.isPresent()) { metrics.getClientErrorsMeter().mark(); response.sendError(400); return; } Continuation continuation = ContinuationSupport.getContinuation(request); continuation.suspend(response); if (artifactOptional.get().getTimeoutMillis().isPresent()) { continuation.setTimeout(artifactOptional.get().getTimeoutMillis().get()); } downloaderCoordinator.register(continuation, artifactOptional.get()); }
@Override public void run() { try { if (!addDownloadRequest()) { if (continuation.isExpired()) { handleContinuationExpired(); return; } reEnqueue(); } } catch (Throwable t) { LOG.error("While trying to enqueue {}", artifactDownloadRequest.getTargetDirectory(), t); exceptionNotifier.notify(String.format("Error enqueuing download (%s)", t.getMessage()), t, ImmutableMap.of("targetDirectory", artifactDownloadRequest.getTargetDirectory())); try { ((HttpServletResponse) continuation.getServletResponse()).sendError(500); } catch (IOException e) { LOG.error("Couldn't send error for {}", artifactDownloadRequest.getTargetDirectory(), e); } finally { continuation.complete(); } } }
@Override public void commit() { try { response.closeOutput(); } catch (final IOException e) { LOGGER.log(Level.WARNING, LocalizationMessages.UNABLE_TO_CLOSE_RESPONSE(), e); } finally { if (continuation.isSuspended()) { continuation.complete(); } LOGGER.log(Level.FINEST, "commit() called"); } }
public void reset() { try { continuation.complete(); } catch (Throwable ex) { // explicit complete call does not seem to work // with the non-Servlet3 Jetty Continuation } obj = null; pendingTimeout = 0; isTimeout = false; }
private void handleContinuationExpired() { try { LOG.info("Continuation expired for {} after {} - returning 500", artifactDownloadRequest, JavaUtils.duration(start)); ((HttpServletResponse) continuation.getServletResponse()).sendError(500, "Hit client timeout"); } catch (Throwable t) { LOG.warn("{} while sending error after continuation for {}", t.getClass().getSimpleName(), artifactDownloadRequest.getTargetDirectory()); } finally { continuation.complete(); } }
@Override public void activate(final MessageQueue queue) { synchronized (queue.getActivationLock()) { queue.setActivationCallback(null); cont.resume(); } } }
public void onTimeout() { if (_listeners!=null) for (ContinuationListener l:_listeners) l.onTimeout(this); }
public void onComplete() { if (_listeners!=null) for (ContinuationListener l:_listeners) l.onComplete(this); }
private HttpServletResponse getResponse() { return (HttpServletResponse) continuation.getServletResponse(); }
public void suspend(ServletResponse response) { _response=response; _responseWrapped=response instanceof ServletResponseWrapper; suspend(); }
@Override public String toString() { return getStatusString(); }
private boolean download() throws Exception { LOG.info("Beginning download {} after {}", artifactDownloadRequest, JavaUtils.duration(start)); if (continuation.isExpired()) { LOG.info("Continuation expired for {}, aborting...", artifactDownloadRequest.getTargetDirectory()); return false; } final Path fetched = artifactManager.fetch(artifactDownloadRequest.getS3Artifact()); downloadListener.notifyDownloadFinished(this); final Path targetDirectory = Paths.get(artifactDownloadRequest.getTargetDirectory()); if (continuation.isExpired()) { LOG.info("Continuation expired for {} after download, aborting...", artifactDownloadRequest.getTargetDirectory()); return false; } if (Objects.toString(fetched.getFileName()).endsWith(".tar.gz")) { artifactManager.untar(fetched, targetDirectory); } else { artifactManager.copy(fetched, targetDirectory, artifactDownloadRequest.getS3Artifact().getFilename()); } LOG.info("Finishing request {} after {}", artifactDownloadRequest.getTargetDirectory(), JavaUtils.duration(start)); getResponse().getOutputStream().close(); return true; }
public void reset() { try { continuation.complete(); } catch (Throwable ex) { // explicit complete call does not seem to work // with the non-Servlet3 Jetty Continuation } obj = null; pendingTimeout = 0; isTimeout = false; }
public void resume() { isResumed = true; isPending = false; continuation.resume(); }
public void onTimeout(AsyncEvent event) throws IOException { _expired=true; listener.onTimeout(Servlet3Continuation.this); } };
@Override public void run() { boolean success = false; try (final Context context = metrics.getDownloadTimer().time()) { success = download(); if (!success) { metrics.getServerErrorsMeter().mark(); getResponse().sendError(500, "Hit client timeout"); } } catch (Throwable t) { metrics.getServerErrorsMeter().mark(); LOG.error("While handling {}", artifactDownloadRequest.getTargetDirectory(), t); exceptionNotifier.notify(String.format("Error handling download (%s)", t.getMessage()), t, ImmutableMap.of("s3Bucket", artifactDownloadRequest.getS3Artifact().getS3Bucket(), "s3Key", artifactDownloadRequest.getS3Artifact().getS3ObjectKey(), "targetDirectory", artifactDownloadRequest.getTargetDirectory())); try { getResponse().sendError(500); } catch (Throwable t2) { LOG.error("While sending error for {}", artifactDownloadRequest.getTargetDirectory(), t2); } } finally { continuation.complete(); } }