예제 #1
0
 @Override
 public boolean send(Message message, long timeout, TimeUnit unit)
     throws SuspendExecution, InterruptedException {
   final ActorRef a = getActor();
   if (a != null) return a.send(message, timeout, unit);
   return true;
 }
예제 #2
0
  /**
   * Sends a request message to an actor, awaits a response value (but no longer than the given
   * timeout) and returns it. This method can be called by any code, even non-actor code. If the
   * actor responds with an error message, a {@link RuntimeException} will be thrown by this method.
   * <br>
   * The message's {@code id} and {@code from} properties may be left unset.
   *
   * <p>This method should be used as in the following example (assuming a {@code String} return
   * value:
   *
   * <pre>{@code
   * String res = call(actor, new MyRequest());
   * }</pre>
   *
   * In the example, {@code MyRequest} extends {@link RequestMessage}. Note how the result of the
   * {@link #from() from} method is passed to the request's constructor, but the message ID isn't.
   *
   * @param <V> the return value's type
   * @param actor the actor to which the request is sent
   * @param timeout the maximum duration to wait for a response
   * @param unit the time unit of the timeout
   * @return the value sent by the actor as a response
   * @throws RuntimeException if the actor responds with an error message, its contained exception
   *     will be thrown, possibly wrapped by a {@link RuntimeException}.
   * @throws TimeoutException if the timeout expires before a response is received from the actor.
   * @throws InterruptedException
   */
  public static <V> V call(final ActorRef actor, RequestMessage<V> m, long timeout, TimeUnit unit)
      throws TimeoutException, InterruptedException, SuspendExecution {
    assert !actor.equals(LocalActor.self()) : "Can't \"call\" self - deadlock guaranteed";

    if (m.getFrom() == null) m.setFrom(from());

    final Actor currentActor;
    if (m.getFrom() instanceof TempActor) currentActor = ((TempActor<?>) m.getFrom()).actor.get();
    else currentActor = Actor.currentActor();

    assert currentActor != null;

    final Object watch = currentActor.watch(actor);

    if (m.getId() == null) m.setId(watch);

    final Object id = m.getId();

    final SelectiveReceiveHelper<Object> helper =
        new SelectiveReceiveHelper<Object>(currentActor) {
          @Override
          protected void handleLifecycleMessage(LifecycleMessage m) {
            if (m instanceof ExitMessage) {
              final ExitMessage exit = (ExitMessage) m;
              if (Objects.equals(exit.getActor(), actor) && exit.getWatch() == watch)
                throw Exceptions.rethrow(exit.getCause());
            }
            super.handleLifecycleMessage(m);
          }
        };
    try {
      actor.sendSync(m);
      final ResponseMessage response =
          (ResponseMessage)
              helper.receive(
                  timeout,
                  unit,
                  new MessageProcessor<Object, Object>() {
                    @Override
                    public Object process(Object m) throws SuspendExecution, InterruptedException {
                      return (m instanceof ResponseMessage
                              && id.equals(((ResponseMessage) m).getId()))
                          ? m
                          : null;
                    }
                  });
      currentActor.unwatch(
          actor,
          watch); // no need to unwatch in case of receiver death, so not doen in finally block

      if (response instanceof ErrorResponseMessage)
        throw Exceptions.rethrow(((ErrorResponseMessage) response).getError());
      return ((ValueResponseMessage<V>) response).getValue();
    } finally {
      if (m.getFrom() instanceof TempActor) ((TempActor) m.getFrom()).done();
    }
  }
예제 #3
0
 private void onMessage(final String message) {
   try {
     userActor.send(new WebDataMessage(ref(), message));
   } catch (SuspendExecution ex) {
     throw new AssertionError(ex);
   }
 }
예제 #4
0
 public WebSocketActorAdapter(
     ChannelHandlerContext ctx, ActorRef<? super WebMessage> userActor) {
   super(userActor.getName(), new WebSocketChannelAdapter(ctx));
   ((WebSocketChannelAdapter) (SendPort) getMailbox()).actor = this;
   this.ctx = ctx;
   this.userActor = userActor;
   watch(userActor);
 }
예제 #5
0
    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));
    }
예제 #6
0
 @Override
 public boolean trySend(Message message) {
   final ActorRef a = getActor();
   if (a != null) return a.trySend(message);
   return true;
 }
예제 #7
0
 @Override
 public void sendSync(Message message) throws SuspendExecution {
   final ActorRef a = getActor();
   if (a != null) a.sendSync(message);
 }
예제 #8
0
 @Override
 public void interrupt() {
   final ActorRef a = getActor();
   if (a != null) a.interrupt();
 }