[ 
https://issues.apache.org/jira/browse/THRIFT-5762?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jens Geyer updated THRIFT-5762:
-------------------------------
    Component/s: Java - Compiler

> Expose service result objects in Java
> -------------------------------------
>
>                 Key: THRIFT-5762
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5762
>             Project: Thrift
>          Issue Type: New Feature
>          Components: Java - Compiler
>            Reporter: Thomas Bruggink
>            Assignee: Thomas Bruggink
>            Priority: Major
>             Fix For: 0.21.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> Some libraries want to bypass the TServer class and handle the full
> service startup manually. For example when building a service that hosts
> multiple thrift services where the IFace type is unknown when handling a
> request.
> For example when you host multiple services on top of netty and through
> an HTTP path you want to route to the correct thrift service. In this
> situation you treat can treat an IFace as an Object and use the
> `getProcessMapView()` method to parse a byte array into a thrift message
> and pass let the `AsyncProcessFunction` handle the invocation.
> To return a correct thrift response it's necessary to write the
> `{service_name}_result` that contains the response args.
> While it is possible to get an incoming args object from the
> (Async)ProcessFunction its unfortunately not possible to get
> a result object without using reflection.
> This PR extends the (Async)ProcessFunction by adding a
> `getEmptyResultInstance` method that returns a new generic `A` (answer)
> that matches the `{service_name}_result` object.
> This allows thrift users to write the following processing code:
> {code:java}
> <I> void handleRequest(
>         TProtocol in,
>         TProtocol out,
>         TBaseAsyncProcessor<I> processor,
>         I asyncIface
> ) throws TException {
>     final Map<String, AsyncProcessFunction<Object, TBase<?, ?>, TBase<?, ?>, 
> TBase<?, ?>>> processMap = (Map) processor.getProcessMapView();
>     final var msg = in.readMessageBegin();
>     final var fn = processMap.get(msg.name);
>     final var args = fn.getEmptyArgsInstance();
>     args.read(in);
>     in.readMessageEnd();
>     if (fn.isOneway()) {
>         return;
>     }
>     fn.start(asyncIface, args, new AsyncMethodCallback<>() {
>         @Override
>         public void onComplete(TBase<?, ?> o) {
>             try {
>                 out.writeMessageBegin(new TMessage(fn.getMethodName(), 
> TMessageType.REPLY, msg.getSeqid()));
>                 final var response_result = fn.getEmptyResultInstance();
>                 final var success_field = 
> response_result.fieldForId(SUCCESS_ID);
>                 ((TBase) response_result).setFieldValue(success_field, o);
>                 response_result.write(out);
>                 out.writeMessageEnd();
>                 out.getTransport().flush();
>             } catch (TException e) {
>                 throw new RuntimeException(e);
>             }
>         }
>         @Override
>         public void onError(Exception e) {
>             try {
>                 out.writeMessageBegin(new TMessage(fn.getMethodName(), 
> TMessageType.EXCEPTION, msg.getSeqid()));
>                 ((TApplicationException) e).write(out);
>                 out.writeMessageEnd();
>                 out.getTransport().flush();
>             } catch (TException ex) {
>                 throw new RuntimeException(ex);
>             }
>         }
>     });
> }
> {code}
> The above example code doesn't need any reference to the original types
> and can dynamically create the correct objects to return a correct
> response.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to