@SuppressWarnings("unchecked") protected void onInvocation(final HandlerContext ctx, final Invocation invocation) { final RemoteReference toReference = invocation.getToReference(); final LocalObjects.LocalObjectEntry<Object> entry = objects.findLocalObjectByReference(toReference); if (entry != null) { final Task<Object> result = InternalUtils.safeInvoke( () -> entry.run(target -> performInvocation(ctx, invocation, entry, target))); // this has to be done here because of exceptions that can occur before performInvocation is // even called. if (invocation.getCompletion() != null) { InternalUtils.linkFuturesOnError(result, invocation.getCompletion()); } } else { if (toReference instanceof Actor) { // on activate will handle the completion; InternalUtils.safeInvoke( () -> executionSerializer.offerJob( toReference, () -> onActivate(ctx, invocation), maxQueueSize)); } else { // missing actor observer invocation.setHops(invocation.getHops() + 1); if (invocation.getCompletion() != null) { invocation.getCompletion().completeExceptionally(new ObserverNotFound()); } } } }
private Task<Void> onActivate(HandlerContext ctx, final Invocation invocation) { // this must run serialized by the remote reference key. LocalObjects.LocalObjectEntry<Object> entry = objects.findLocalObjectByReference(invocation.getToReference()); if (entry == null) { objects.registerLocalObject(invocation.getToReference(), null); entry = objects.findLocalObjectByReference(invocation.getToReference()); } // queues the invocation final LocalObjects.LocalObjectEntry<Object> theEntry = entry; final Task result = entry.run(target -> performInvocation(ctx, invocation, theEntry, target)); if (invocation.getCompletion() != null) { InternalUtils.linkFuturesOnError(result, invocation.getCompletion()); } // yielding since we blocked the entry before running on activate (serialized execution) return Task.done(); }