jsr369-experts@servlet-spec.java.net

[jsr369-experts] Re: [servlet-spec users] Re: Re: Reactive Streams and Servlet 4: synergy or no?

From: Wenbo Zhu <wenboz_at_google.com>
Date: Thu, 1 Oct 2015 17:54:21 -0700

A few extra notes:

It seems that reactive streams follow the "push delivery + poll based
flow-control" style.
- there are no separate read and write APIs so the "flow" API does look a
lot cleaner.
- HTTP/2 or QUIC uses window based flow control, so the "flow" API maps
well to the underlying stream-level flow-control

However, I don't believe it's possible, or intended, to align the flow API
with transport level flow control, e.g. when/whether to allow returning
credits, different levels of flow control windows.







H

On Wed, Sep 30, 2015 at 5:07 PM, Wenbo Zhu <wenboz_at_google.com> wrote:

> Here is a short survey on different flow-control API styles and their
> trade-offs:
>
> 1. flow-control provides the mechanism to protect applications (process)
> from being overloaded due to (completely) async read/writes
> 2. I haven't looked at reactive streams closely so not sure whether/where
> it fits
>
> ===
>
> Reads
>
> 1. Push delivery + explicit flow-control signals
>
> API pattern:
>
> callback#onMessage(msgs) // messages are delivered to applications
> stream#startFlowControl() // signal to the other end to stop writing
> stream#stopFlowControl() // signal to the other end to resume writing
>
> Examples: Node streams, WebSocket
>
> 2. Push delivery + poll based flow-control
>
> API pattern:
>
> stream#readMore()
> callback#onMessage(msgs) // only to be invoked following a readMore()
>
> Examples: window based flow control
>
> Notes:
> - assuming onMessage() is completely non-blocking
> - readMore() may specify maximum data to read
> - readMore() may be implicitly called when onMessage() returns
>
> 3. Pull delivery (epoll style)
>
> API pattern:
>
> stream#notifyWhenReadable(callback)
> stream#read(...) // may specify the size to read
>
> Examples: 3.1 async I/O, ....
>
>
> ====
>
> Writes
>
> 1.
>
> stream#write(msgs)
> callback#onFlowControl(state) // OK to write more or not
>
> 2.
>
> stream#writeMore(callback) // intend to write, may also specify the
> size to write
> stream#write(msgs) // only to be invoked from the callback
>
> 3.
>
> stream#notifyWhenWritable(callback)
> stream#write(msgs)
>
>
> ===
>
> Trade-offs (reads)
>
> 1.
>
> - no transport coupling
> - timed delivery is guaranteed as flow control is out of the critical path
> - timed flow-control is not guaranteed, as decided by transport and
> run-time implementation details
>
> 2.
>
> - it’s possible to guarantee both timed delivery and flow control with
> explicit readMore() controls
> - when the underlying transport is TCP (e.g. HTTP/1.1), explicit
> readMore() may not be supported
> - complicated
>
> 3.
>
> - default behavior will protect the app in a very straightforward way,
> esp. by leveraging the buffer owned by the transport
> - default behavior hurts throughput, esp. if the link is slow
>
>
>
>
> On Wed, Sep 23, 2015 at 3:54 PM, Edward Burns <edward.burns_at_oracle.com>
> wrote:
>
>> >>>>> On Wed, 23 Sep 2015 15:05:03 -0700, Wenbo Zhu <wenboz_at_google.com>
>> said:
>>
>> WZ> Sorry about the delay.
>>
>> WZ> I have done a survey on different styles for enabling flow-control
>> with
>> WZ> async apis. Happy to share, after I clean up the doc a little bit.
>>
>> Yes please.
>>
>> Ed
>> --
>> | edward.burns_at_oracle.com | office: +1 407 458 0017
>> | 31 Business days til JavaOne 2015
>> | 46 Business days til DOAG 2015
>>
>
>