HttpActorAdapter( ActorRef<? super HttpRequest> userActor, Context actorContext, String httpResponseEncoderName) { super("HttpActorAdapter", new HttpChannelAdapter(actorContext, httpResponseEncoderName)); if (actorContext.watch()) ((HttpChannelAdapter) (SendPort) getMailbox()).actor = this; this.userActor = userActor; this.context = actorContext; }
final void service(ChannelHandlerContext ctx, FullHttpRequest req) throws SuspendExecution { if (context.watch()) watchToken = watch(userActor); this.ctx = ctx; this.req = req; if (isDone()) { handleDeath(getDeathCause()); return; } userActor.send(new HttpRequestWrapper(ref(), ctx, req)); }
@Override protected final void die(Throwable cause) { if (dead) return; dead = true; super.die(cause); try { context.invalidate(); } catch (final Exception ignored) { } // Ensure to release references to server objects unwatch(); userActor = null; watchToken = null; context = null; ctx = null; req = null; }
private void addActorToContextAndUnlock( Context actorContext, ActorImpl actor, ReentrantLock lock) { actorContext.getAttachments().put(ACTOR_KEY, actor); lock.unlock(); }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) throws SuspendExecution { // Handle a bad request. if (!req.getDecoderResult().isSuccess()) { sendHttpResponse( ctx, req, new DefaultFullHttpResponse(req.getProtocolVersion(), BAD_REQUEST), false); return; } final String uri = req.getUri(); final Context actorCtx = selector.get(ctx, req); assert actorCtx != null; final ReentrantLock lock = actorCtx.getLock(); assert lock != null; lock.lock(); try { final ActorRef<? extends WebMessage> userActorRef = actorCtx.getRef(); ActorImpl internalActor = (ActorImpl) actorCtx.getAttachments().get(ACTOR_KEY); if (userActorRef != null) { if (actorCtx.handlesWithWebSocket(uri)) { if (internalActor == null || !(internalActor instanceof WebSocketActorAdapter)) { //noinspection unchecked webSocketActor = new WebSocketActorAdapter(ctx, (ActorRef<? super WebMessage>) userActorRef); addActorToContextAndUnlock(actorCtx, webSocketActor, lock); } // Handshake final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(uri, null, true); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { @SuppressWarnings("unchecked") final ActorRef<WebMessage> userActorRef0 = (ActorRef<WebMessage>) webSocketActor.userActor; handshaker .handshake(ctx.channel(), req) .addListener( new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(ChannelFuture future) throws Exception { FiberUtil.runInFiber( new SuspendableRunnable() { @Override public void run() throws SuspendExecution, InterruptedException { userActorRef0.send( new WebSocketOpened(WebActorHandler.this.webSocketActor.ref())); } }); } }); } return; } else if (actorCtx.handlesWithHttp(uri)) { if (internalActor == null || !(internalActor instanceof HttpActorAdapter)) { //noinspection unchecked internalActor = new HttpActorAdapter( (ActorRef<HttpRequest>) userActorRef, actorCtx, httpResponseEncoderName); addActorToContextAndUnlock(actorCtx, internalActor, lock); } //noinspection unchecked ((HttpActorAdapter) internalActor).service(ctx, req); return; } } } finally { if (lock.isHeldByCurrentStrand() && lock.isLocked()) lock.unlock(); } sendHttpResponse( ctx, req, new DefaultFullHttpResponse(req.getProtocolVersion(), NOT_FOUND), false); }