We're thinking about doing something like this over in Avro:
https://issues.apache.org/jira/browse/AVRO-406

That JIRA has some of the discussion about the difficulties inherent in such
a feature.

-Todd

On Sun, Feb 28, 2010 at 11:29 AM, Bryan Duxbury <br...@rapleaf.com> wrote:

> I think this may be a good new feature to explore. It wouldn't be the first
> time that someone has thought that this would be something useful to have
> in
> Thrift.
>
> I think it'd be something good to start working on and see what the
> implications are. In particular, I'd like to see what kind of changes we'd
> have to do to our server implementations.
>
> -Bryan
>
> On Sun, Feb 28, 2010 at 9:28 AM, David Reiss <dre...@facebook.com> wrote:
>
> > Thanks for the well-written proposal.  If we were to implement this,
> > I think you have described the way we would do it.
> >
> > My main objection to implementing streaming RPC is a fear of feature
> creep.
> > Keeping Thrift small(ish) makes it a lot easier to make sure that all of
> > the language implementations have good support for all features.
> >
> > What to other committers think?
> >
> > --David
> >
> > Jeff Brown wrote:
> > > Today I encountered a case where it would be useful if Thrift provided
> > > native support for streaming RPC.  To be sure, everything I needed to
> do
> > I
> > > could implement (albeit with difficult) using the existing
> infrastructure
> > > but I feel it could be made much better by extending the IDL.
> > >
> > > Please forgive me if this idea has already been discussed here.
> > >
> > > *Background:
> > > *
> > > Sometimes a service needs to perform a long-running operation that
> > > periodically yields output.  Rather than waiting for the full result to
> > be
> > > processed, it would be nice if clients can get a head start on the
> > > intermediate output.  This is particularly important when the results
> are
> > > intended to be presented to an end user.
> > >
> > > A simple way to accomplish this trick is to allow services to write
> > multiple
> > > messages to the protocol.
> > >
> > >
> > > *Proposed IDL extensions:
> > > *
> > > * Option 1: New *stream* keyword admitted as a method return type.
> > >
> > > *struct Response
> > > {
> > >     1: required string item;
> > > }
> > >
> > > service Example
> > > {
> > >     stream<Response> Method()
> > > }
> > > *
> > > With this approach, the method can be conceived of as returning a
> stream
> > of
> > > zero or more responses.  This is particularly appealing because it
> > leverages
> > > familiar patterns of iteration.
> > >
> > > The server side implementation can be conveniently written as an
> iterator
> > > method.  Here's a C# example.  Similar syntax exists in many popular
> > > languages but it is not essential for the API.
> > >
> > > public IEnumerable<Response> Method()
> > > {
> > >     yield return new Response() { Item = "a" };
> > >     // expensive work
> > >     yield return new Response() { Item = "b" };
> > > }
> > >
> > > Likewise the client side can be modeled as a consumer of an iterator.
> > >
> > > public void Consumer()
> > > {
> > >     IEnumerable<Response> responses = client.Method();
> > >     foreach (Response response in responses)
> > >     {
> > >         Console.WriteLine(response.item);
> > >     }
> > > }
> > >
> > > * Option 2: New *streams* keyword admitted as an auxiliary clause
> similar
> > to
> > > throws.
> > >
> > > *struct Item
> > > {
> > >     1: required string name
> > > }
> > >
> > > struct Response
> > > {
> > >     1: required string summary
> > > }
> > >
> > > service Example
> > > {
> > >     Response Method() streams(1: Item item)
> > > }
> > > *
> > > With this approach, the method has both a standard return value and can
> > > stream items on the side.  It could potentially be set up to allow a
> > method
> > > to provide multiple streams.
> > >
> > > The server side implementation is straightforward.  The method just
> needs
> > to
> > > be provided with an object that can publish to the stream in addition
> to
> > > whatever arguments it receives.
> > >
> > > public Response Method(TStream<Item> stream)
> > > {
> > >     stream.Send(new Item() { name = "a" });
> > >     // expensive work
> > >     stream.Send(new Item() { name = "b" });
> > >     return new Reponse() { summary = "2 items" });
> > > }
> > >
> > > The client side is not so nice since we can't leverage the iterator
> > pattern
> > > because we could have multiple distinct streams.  Here's a synchronous
> > > implementation using a callback.
> > >
> > > public void Consumer()
> > > {
> > >     TStreamCallback<Item> callback = (item) => Console.WriteLine(
> > item.name);
> > >     Response response = client.Method(callback);
> > > }
> > >
> > >
> > > *Proposed protocol extension:*
> > >
> > > To make this work, the server needs to be able to send multiple stream
> > > messages before the final reply.
> > >
> > > One way to do that is to add a new TMessageType value called Stream
> that
> > > indicates that the TMessage contains a streaming response.  When the
> > client
> > > receives a message of type Stream, it makes the content available to
> the
> > > consumer and then (conceptually) loops again until it sees a final
> > message
> > > of type Reply.
> > >
> > > The final reply message might only indicate success / failure if the
> > stream
> > > is empty or if everything of interest has already been streamed by the
> > time
> > > the method returns.
> > >
> > > Adding a new TMessageType is a non-invasive change that won't break
> > existing
> > > clients or servers unless they use streaming methods.
> > >
> > > Jeff.
> >
>

Reply via email to