@SuppressWarnings("unchecked") protected Task<Object> performInvocation( HandlerContext ctx, final Invocation invocation, final LocalObjects.LocalObjectEntry entry, final LocalObjects.LocalObjectEntry target) { if (logger.isDebugEnabled()) { logger.debug("Invoking {} ", invocation); } try { if (target == null || target.isDeactivated()) { // if the entry is deactivated, forward the message back to the net. ctx.write(invocation); return Task.fromValue(null); } if (target.getObject() == null) { if (target instanceof ObserverEntry) { return Task.fromException(new ObserverNotFound()); } ctx.write(invocation); return Task.fromValue(null); } final ObjectInvoker invoker = DefaultDescriptorFactory.get().getInvoker(target.getObject().getClass()); final ActorTaskContext context = ActorTaskContext.current(); if (invocation.getHeaders() != null && invocation.getHeaders().size() > 0 && runtime.getStickyHeaders() != null) { for (Map.Entry e : invocation.getHeaders().entrySet()) { if (runtime.getStickyHeaders().contains(e.getKey())) { context.setProperty(String.valueOf(e.getKey()), e.getValue()); } } } // todo: it would be nice to separate this last part into another handler (InvocationHandler) // to be able intercept the invocation right before it actually happens, good for logging and // metrics if (context != null) { context.setRuntime(runtime); } else { runtime.bind(); } final Task result = invoker.safeInvoke(target.getObject(), invocation.getMethodId(), invocation.getParams()); if (invocation.getCompletion() != null) { InternalUtils.linkFutures(result, invocation.getCompletion()); } return result; } catch (Throwable exception) { if (logger.isDebugEnabled()) { logger.debug("Unknown application error. ", exception); } if (invocation.getCompletion() != null) { invocation.getCompletion().completeExceptionally(exception); } return Task.fromException(exception); } }
@Override public void onRead(HandlerContext ctx, Object msg) { if (msg instanceof Invocation) { onInvocation(ctx, (Invocation) msg); } else { ctx.fireRead(msg); } }
@Override public Task write(final HandlerContext ctx, final Object msg) throws Exception { if (!(msg instanceof Pair)) { return ctx.write(msg); } Pair<NodeAddress, byte[]> message = (Pair<NodeAddress, byte[]>) msg; clusterPeer.sendMessage(message.getLeft(), message.getRight()); return Task.done(); }
@Override public Task write(final HandlerContext ctx, final Object msg) throws Exception { return ctx.write(msg); }
@Override public Task connect(final HandlerContext ctx, final Object param) throws Exception { clusterPeer.registerMessageReceiver((n, m) -> ctx.fireRead(Pair.of(n, m))); return clusterPeer.join(clusterName, nodeName).thenRun(() -> ctx.fireActive()); }