playframework-2.3 Akka-Async交互移植?

时间:2014-07-17 09:18:43

标签: java akka porting playframework-2.2 playframework-2.3

我有一些旧的playframework 2.2 java webservice与akka交互,现在我应该将它们移植到playframework 2.3。

但是,async已被弃用,即使在阅读了有关异步移植(http://www.playframework.com/documentation/2.3.x/JavaAsync)的文档后,我也无法理解如何将其应用到我的案例中(以下代码):

  • 我必须在开始构建我的回复(ok())之前等待超时/ akka服务器回复,否则我将阻止该线程。
  • 我也应该使actorselection异步。

  • 我应该让akka服务器回复解析/回复构建异步

我环顾四周,即使在类型安全的模板中,我也无法找到此类互动的示例。

我怎么能这样做?

/* playframework 2.2 code */

public class Resolve extends Controller {

    private final static String RESOLVER_ACTOR = play.Play.application().configuration().getString("actor.resolve");

    @CorsRest
    @VerboseRest
    @RequireAuthentication
    @BodyParser.Of(BodyParser.Json.class)
    public static Result getJsonTree() {
        JsonNode json = request().body().asJson();

        ProtoBufMessages.ResolveRequest msg;
        ResolveRequestInput input;

        try {
            input = new ResolveRequestInput(json);
        } catch (rest.exceptions.MalformedInputException mie) {
            return badRequest(mie.getMessage());
        }

        msg = ((ProtoBufMessages.ResolveRequest)input.getMessage());

        ActorSelection resolver = Akka.system().actorSelection(RESOLVER_ACTOR);


        Timeout tim = new Timeout(Duration.create(4, "seconds"));

        Future<Object> fut = Patterns.ask(resolver, input.getMessage(), tim);

        return async (
                F.Promise.wrap(fut).map(
                        new F.Function<Object, Result>() {
                            public Result apply(Object response) {
                                ProtoBufMessages.ResolveReply rsp = ((ProtoBufMessages.ResolveReply)response);
                                ResolveOutput output = new ResolveOutput(rsp);
                                return ok(output.getJsonReply());
                            }
                        }
                )
        );
    }
}

1 个答案:

答案 0 :(得分:0)

我出来了以下代码

public class Resolve extends Controller {

    private final static String RESOLVER_ACTOR = play.Play.application().configuration().getString("actor.resolve");
    private final static BrainProtoMessages.ResolveReply request_error = BrainProtoMessages.ResolveReply.newBuilder()
        .setReturnCode(BResults.REQUEST_FAILED)
        .build();

    @CorsRest
    @VerboseRest
    @RequireAuthentication
    @BodyParser.Of(BodyParser.Json.class)

public static Result resolve_map() {

    final ResolveRequestInput input;
    final F.Promise<ActorSelection> selected_target;
    final F.Promise<Future<Object>> backend_request;
    final F.Promise<BrainProtoMessages.ResolveReply> backend_reply;
    final F.Promise<ObjectNode> decode_json;
    final F.Promise<Result> ok_result;
    final JsonNode json = request().body().asJson();

    try {
        input = new ResolveRequestInput(json);
    } catch (rest.exceptions.MalformedInputException mie) {
        return badRequest(mie.getMessage());
    }

    selected_target = F.Promise.promise(
      new F.Function0<ActorSelection>() {
          @Override
          public ActorSelection apply() throws Throwable {
              return Akka.system().actorSelection(RESOLVER_ACTOR);    
          }
      }      
    );

    backend_request =
            selected_target.map(
                    new F.Function<ActorSelection, Future<Object>>() {
                        @Override
                        public Future<Object> apply(ActorSelection actorSelection) throws Throwable {
                            return Patterns.ask(actorSelection, input.getMessage(),new Timeout(Duration.create(4, "seconds")));
                        }
                    }
            );

    backend_reply = backend_request.map(

            new F.Function<Future<Object>, BrainProtoMessages.ResolveReply>() {
                @Override
                public BrainProtoMessages.ResolveReply apply(Future<Object> akka_reply) throws Throwable {
                    try {
                        return (BrainProtoMessages.ResolveReply) Await.result(akka_reply, Duration.create(4, "seconds"));
                    }catch(Exception error)
                    {
                        return request_error;
                    }    
                }
            }
    );

    decode_json = backend_reply.map(

            new F.Function<BrainProtoMessages.ResolveReply, ObjectNode>() {
                @Override
                public ObjectNode apply(BrainProtoMessages.ResolveReply response) throws Throwable {
                    return new ResolveOutput(response).getJsonReply();
                }
            }
        );

    ok_result = decode_json.map(
            new F.Function<ObjectNode, Result>() {
                @Override
                public Result apply(ObjectNode reply) {
                    return ok(reply);
                }
            }
    );

    try {
        return ok_result.get(8000);
    }catch(Exception error)
    {
        return internalServerError();
    }

}

}