Пример #1
0
 @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());
       }
     }
   }
 }
Пример #2
0
  @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);
    }
  }
Пример #3
0
 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();
 }