private void sendNextResourceData() { if (LOG.isDebugEnabled()) LOG.debug("{} sendNextResourceData active: {}", hashCode(), active.get()); if (active.compareAndSet(false, true)) { PushResource resource = queue.poll(); if (resource != null) { if (LOG.isDebugEnabled()) LOG.debug("Opening new push channel for: {}", resource); HttpChannelOverSPDY pushChannel = newHttpChannelOverSPDY(resource.getPushStream(), resource.getPushRequestHeaders()); pushChannel.requestStart(resource.getPushRequestHeaders(), true); return; } if (active.compareAndSet(true, false)) { if (queue.peek() != null) sendNextResourceData(); } else { throw new IllegalStateException("active must not be false here! Concurrency bug!"); } } }
private void pushResource(String pushResource) { Fields.Field scheme = requestHeaders.get(HTTPSPDYHeader.SCHEME.name(version)); Fields.Field host = requestHeaders.get(HTTPSPDYHeader.HOST.name(version)); Fields.Field uri = requestHeaders.get(HTTPSPDYHeader.URI.name(version)); final Fields pushHeaders = createPushHeaders(scheme, host, pushResource); final Fields pushRequestHeaders = createRequestHeaders(scheme, host, uri, pushResource); stream.push(new PushInfo(pushHeaders, false), new Promise<Stream>() { @Override public void succeeded(Stream pushStream) { if (LOG.isDebugEnabled()) LOG.debug("Headers pushed for {} on {}", pushHeaders.get(HTTPSPDYHeader.URI.name(version)), pushStream); queue.offer(new PushResource(pushStream, pushRequestHeaders)); sendNextResourceData(); } @Override public void failed(Throwable x) { LOG.debug("Creating push stream failed.", x); sendNextResourceData(); } }); }
private void reply(Stream stream, ReplyInfo replyInfo, Callback callback) { if (!stream.isUnidirectional()) stream.reply(replyInfo, callback); else stream.headers(new HeadersInfo(replyInfo.getHeaders(), replyInfo.isClose()), callback); Fields responseHeaders = replyInfo.getHeaders(); if (responseHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().startsWith("200") && !stream.isClosed()) { Set<String> pushResources = pushStrategy.apply(stream, requestHeaders, responseHeaders); if (pushResources.size() > 0) { PushResourceCoordinator pushResourceCoordinator = new PushResourceCoordinator(pushResources); pushResourceCoordinator.coordinate(); } } }
private void coordinate() { if (LOG.isDebugEnabled()) LOG.debug("Pushing resources: {}", resources); // Must send all push frames to the client at once before we // return from this method and send the main resource data for (String pushResource : resources) pushResource(pushResource); }
private void complete() { if (!active.compareAndSet(true, false)) throw new IllegalStateException(); sendNextResourceData(); }