You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Allen George (Jira)" <ji...@apache.org> on 2022/04/17 02:22:00 UTC

[jira] [Comment Edited] (THRIFT-5559) Processor can be implemented on handler trait itself

    [ https://issues.apache.org/jira/browse/THRIFT-5559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17523266#comment-17523266 ] 

Allen George edited comment on THRIFT-5559 at 4/17/22 2:21 AM:
---------------------------------------------------------------

For example, consider:

{noformat}
Trait_A
+ - Trait_B
    +- Uses types from E
+ - Trait_C
    +- Trait D
{noformat}

When the generator runs it can:

1. Generate a trait definition for {{Trait_D}}
2. Generate a trait definition for {{Trait_C}} and also simply say {{Trait_C : Trait_D}} to enforce the inheritance, without caring what methods/types {{Trait_D}} has
3. Generate a trait definition for {{Trait_B}} and during that, resolve all the types from {{E}}
4. Generate a trait definition for {{Trait_A}} and also simply say {{Trait_A : Trait B + Trait_C}} without caring about the underlying methods/types {{Trait_B}}, {{Trait_C}} or {{E}} has

Also note that you have to generate a corresponding processor for {{A}}, {{B}}, {{C}} and {{D}}. This is very straightforward because all you're doing is defining it in terms of the trait name defined in the local file, not caring about how complex its inheritance hierarchy is.

If you run the generator on https://github.com/apache/thrift/blob/master/lib/rs/test/src/bin/kitchen_sink_server.rs you can see this at work.


was (Author: allengeorge):
For example, consider:

{noformat}
Trait_A
+ - Trait_B
    +- Uses types from E
+ - Trait_C
    +- Trait D
{noformat}

When the generator runs it can:

1. Generate a trait definition for {{Trait_D}}
2. Generate a trait definition for {{Trait_C}} and also simply say {{Trait_C : Trait_D}} to enforce the inheritance
3. Generate a trait definition for {{Trait_B}} and during that, resolve all the types from {{E}}
4. Generate a trait definition for {{Trait_A}} and also simply say {{Trait_A : Trait B + Trait_C}} without caring about the underlying methods/types to enforce the inheritance.

Also note that you have to generate a corresponding processor for {{A}}, {{B}}, {{C}} and {{D}}. This is very straightforward because all you're doing is defining it in terms of the trait name defined in the local file, not caring about how complex its inheritance hierarchy is.

If you run the generator on https://github.com/apache/thrift/blob/master/lib/rs/test/src/bin/kitchen_sink_server.rs you can see this at work.

> Processor can be implemented on handler trait itself
> ----------------------------------------------------
>
>                 Key: THRIFT-5559
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5559
>             Project: Thrift
>          Issue Type: Proposal
>          Components: Rust - Compiler
>            Reporter: Francisco Ayala
>            Priority: Major
>
> Right now the compiler produces code of the following form:
>  
> {code:java}
> pub trait ServiceSyncHandler {
>   fn handle_test_episode(&self, arg: types::Type1) -> thrift::Result<types::Type1>;
> }
> pub struct ServiceSyncProcessor<H: ServiceSyncHandler> {
>   handler: H,
> }
> impl <H: ServiceSyncHandler> ServiceSyncProcessor<H> {
>   pub fn new(handler: H) -> ServiceSyncProcessor<H> {
>     ServiceSyncProcessor {
>       handler,
>     }
>   }
>   fn process_test_episode(&self, incoming_sequence_number: i32, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {
>     TServiceProcessFunctions::process_test_episode(&self.handler, incoming_sequence_number, i_prot, o_prot)
>   }
> } {code}
> There is this object called "ServiceSyncProcessor" which wraps the actual handler. However it has no other fields, and also only ever utilizes a reference to the handler. Thus my question is why aren't the methods implemented on the type itself? Like this:
>  
>  
> {code:java}
> impl dyn ServiceSyncHandler {
>     fn process_test_episode(
>         &self,
>         incoming_sequence_number: i32,
>         i_prot: &mut dyn TInputProtocol,
>         o_prot: &mut dyn TOutputProtocol,
>     ) -> thrift::Result<()> {
>         TServiceProcessFunctions::process_test_episode(
>             self,
>             incoming_sequence_number,
>             i_prot,
>             o_prot,
>         )
>     }
> }{code}
> In my case this is limiting since I don't want the server to take ownership of the processor object, since I'm doing everything in a single thread and need this object for other purposes. It was easy enough implementing my own server, but this is now blocking me.
>  
> My questions are thus: Is there a reason for this design? Would implementing the alternative I proposed be a welcome addition?
>  



--
This message was sent by Atlassian Jira
(v8.20.1#820001)