You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Aleksey Pesternikov (JIRA)" <ji...@apache.org> on 2014/05/10 23:56:07 UTC

[jira] [Commented] (THRIFT-1948) Add a stream type

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

Aleksey Pesternikov commented on THRIFT-1948:
---------------------------------------------

Hi
It would be awesome to move this important feature forward.
I put some thoughts together as specification draft here:
https://docs.google.com/document/d/1BfbgtnJoKBiwgTg1xuNvC126eIUVIZvaya9Cv4VC1bk
For additional bonus, here is a java implementation:
https://github.com/apesternikov/thrift/tree/streaming
implemented: one way (client-to-server and server-to-client) streaming for binary protocol. compact protocol should be trivial to add.
no receiver side cancellation is implemented, so the only way to cancel from receiver side is to close connection (which is totally legitimate though)
There are many questions regarding interface, especially for C++
any thoughts?


> Add a stream type
> -----------------
>
>                 Key: THRIFT-1948
>                 URL: https://issues.apache.org/jira/browse/THRIFT-1948
>             Project: Thrift
>          Issue Type: New Feature
>            Reporter: Carl Yeksigian
>            Assignee: Carl Yeksigian
>
> This is a proposal for an addition to the Thrift IDL, which allows for sending chunks of data between the server and the client without having the whole message in memory at the start of the communication.
> Here are two use cases where I have been thinking about the possibility of using streams.
> LockServer.thrift:
> {code}
> struct Update {
> 	1: required string lock_handle,
> 	2: required i64 owner
> }
> service LockService {
> 	stream<Update> updates_for(1: string prefix)
> }
> {code}
> This would allow the LockServer to push out updates that happen based on the prefix the client has specified, rather than the constant polling that would currently be required to imitate this interface.
> ManyResults.thrift:
> {code}
> service QueryProvider {
>   stream<Result> run_query()
> }
> {code}
> This allows the query provider to run the query and send back the results as they come in, rather than having to bunch them up, or provide a way to page through the results to the client.
> The new keyword, "stream<T>", would indicate that there is a series of values typed T which would be communicated between client and server. Stream would have three primitives:
> {code}
> next(T)
> error(TException)
> end()
> {code}
> Protocols would be enhanced with the following methods:
> {code}
> writeStreamBegin(etype, streamid)
> writeStreamNext(streamid, streamMessageType)
> writeStreamNextEnd()
> writeStreamErrorEnd()
> etype, streamid = readStreamBegin()
> streamid, streamMessageType = readStreamNext()
> readStreamNextEnd()
> readStreamErrorEnd()
> {code}
> streamMessageType is one of the following:
> # next
>   This means that the message will be of the element type.
> # error
>   An exception was thrown during materialization of the stream.
>   The stream is now closed.
> # end
>   This means that the stream is finished.
>   The stream is now closed.
> Once all streams are closed, readMessageEnd should be called. Before the first writeStreamNext() could be called, the message should otherwise be complete. Otherwise, an exception should be raised.
> It is possible that an exception will be thrown while the stream is being materialized; however, this can only occur inside of a service. In this case, error() will be called; the exception should be one of the exceptions that the service call would have thrown. The values that were generated before the exception will generally be valid, but may only have meaning if the stream is ended. All streams which are currently open may get the same exception.
> If the following service was defined:
> {code}
> stream<i64> random_numbers(stream<i64> max)
> {code}
> A sample session from client to server would be:
> {code}
> writeMessageBegin()
> writeStreamBegin(I64, 0)
> writeStreamNext(0, next)
> writeI64(10)
> writeStreamNextEnd()
> writeStreamNext(0, end)
> writeMessageEnd()
> {code}
> A sample session from server to client would be:
> {code}
> writeMessageBegin()
> writeStreamBegin(i64, 0)
> writeStreamNext(0, next)
> writeI64(3)
> writeStreamNextEnd()
> writeStreamNext(0, end)
> writeMessageEnd()
> {code}
> This change would not be compatible with previous versions of Thrift. Also, for languages which do not support this type of streaming, it could be translated into a list.



--
This message was sent by Atlassian JIRA
(v6.2#6252)