queue.heartBeat();
final OutputStreamWriteAdapter writer;
if (isSSERequest(request)) {
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(getSSETimeout());
queue.setTimeout(getSSETimeout() + 5000);
final HttpServletResponse asynResponse = (HttpServletResponse) asyncContext.getResponse();
prepareSSE(asynResponse);
prepareSSEContinue(asynResponse);
asynResponse.getOutputStream().flush();
writer = new OutputStreamWriteAdapter(asynResponse.getOutputStream());
asyncContext.addListener(new AsyncListener() {
@Override
public void onComplete(final AsyncEvent event) throws IOException {
synchronized (queue.getActivationLock()) {
queue.setActivationCallback(null);
asyncContext.complete();
}
}
@Override
public void onTimeout(final AsyncEvent event) throws IOException {
onComplete(event);
}
@Override
public void onError(final AsyncEvent event) throws IOException {
queue.setActivationCallback(null);
}
@Override
public void onStartAsync(final AsyncEvent event) throws IOException {
}
});
synchronized (queue.getActivationLock()) {
if (queue.messagesWaiting()) {
queue.poll(writer);
writer.write(SSE_TERMINATION_BYTES);
writer.flush();
return;
}
queue.setActivationCallback(new QueueActivationCallback() {
@Override
public void activate(final MessageQueue queue) {
try {
queue.poll(writer);
writer.write(SSE_TERMINATION_BYTES);
queue.heartBeat();
writer.flush();
prepareSSEContinue(asynResponse);
}
catch (IOException e) {
log.debug("Closing queue with id: " + queue.getSession().getSessionId() + " due to IOException", e);
queue.stopQueue();
}
catch (final Throwable t) {
try {
writeExceptionToOutputStream((HttpServletResponse) asyncContext.getResponse(), t);
}
catch (Throwable t2) {
log.debug("Failed to write exception to dead client", t2);
}
}
}
});
}
}
else {
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(60000);
queue.setTimeout(65000);
writer = new OutputStreamWriteAdapter(asyncContext.getResponse().getOutputStream());
asyncContext.addListener(new AsyncListener() {
@Override
public void onComplete(final AsyncEvent event) throws IOException {
synchronized (queue.getActivationLock()) {
queue.setActivationCallback(null);
asyncContext.complete();
}
}
@Override
public void onTimeout(final AsyncEvent event) throws IOException {
onComplete(event);
}
@Override
public void onError(final AsyncEvent event) throws IOException {
queue.setActivationCallback(null);
}
@Override
public void onStartAsync(final AsyncEvent event) throws IOException {
}
});
synchronized (queue.getActivationLock()) {
if (queue.messagesWaiting()) {
queue.poll(writer);
asyncContext.complete();
return;
}
queue.setActivationCallback(new QueueActivationCallback() {
@Override
public void activate(final MessageQueue queue) {
try {
queue.poll(writer);
queue.setActivationCallback(null);
queue.heartBeat();
writer.flush();
}
catch (IOException e) {
log.debug("Closing queue with id: " + queue.getSession().getSessionId() + " due to IOException", e);
}
catch (final Throwable t) {
try {
writeExceptionToOutputStream((HttpServletResponse) asyncContext.getResponse(), t);
}
catch (Throwable t2) {
log.debug("Failed to write exception to dead client", t2);
}
}
finally {
asyncContext.complete();
}
}
});
writer.flush();
}