James Roper james at lightbend.com
Fri Jul 27 01:13:07 UTC 2018

Hi Douglas,

I'm not for this change.

One problem with it is that there are quite a number of other standard
APIs, both in the JDK (eg the new HTTP client) as well as in Java EE (eg
JAX-RS, CDI, and a number of the new MicroProfile APIs) plus a myriad of
open source libraries that have already embraced CompletionStage as the
abstraction to use to asynchronously provide exactly one value, or to
signal completion (a la CompletionStage<Void>). Some of these APIs are
looking to or have adopted Reactive Streams/juc.Flow, but only for
streaming, not for asynchronous single values. When all libraries use the
same abstraction for the same use case, then they become easy to use and
integrate with each other. When they use different abstractions, then you
need bridges to integrate them with each other, which has the effect of
making it harder for end users to use them, the code they write becomes
harder to read due to all the bridging wrappers, etc.

So, if let's say I need to load something from the database, then make an
HTTP call, if both the database adapter and that HTTP client use
CompletionStage, this is easy as:

CompletionStage<Response> response = database.executeQuery()
  .thenCompose(result ->

I can add other asynchronous operations from other libraries to my hearts
content and the code still stays easy to read because everything is using
the same abstraction. However, if ADBA used reactive streams for this, then
you would need to convert the publisher to a CompletionStage. It would be
the only API in the Java standards ecosystem that uses streams in this way,
which would make it stand out like a sore thumb, every other Java standard
that supported asynchronous IO would integrate nicely together using
CompletionStage, but when it came to using ADBA, everyone would have to use
a bridging wrapper.

Reactive streams is great for streams - I am a massive proponent of it
being used for the right use case. But it includes a lot of mechanics (and
performance overhead) to meet the needs that streams have, including
handshaking to establish a subscription, and then tokens for backpressure.
A single value made asynchronously available in the future is not a stream,
it doesn't require back pressure because there's only one value, not
potentially infinite, it doesn't require the overhead of a subscription
because the semantics are much simpler. These things get in the way both
performance wise and they also make it more complex to use and implement.
Of course, you *can* use a stream to provide a single value, I'm not
disputing that. You can also use a Collection to represent a single value
that may or may not be present - but that's not what it's designed for,
java.util.Optional is designed and optimised for that, and makes it much
clearer to uses when they see it what is actually being provided. The same
goes with CompletionStage vs Publisher.



On Fri, 27 Jul 2018 at 02:04, Douglas Surber <douglas.surber at oracle.com>

> I presented ADBA at the San Francisco Java Users Group last night. It was
> great. There were a number of folks who were strong advocates of reactive
> streams and we talked for well over an hour after the presentation ended.
> The kind of feedback we got last night is critical to the future success of
> this project.
> This discussion resulted in a concrete proposal to make ADBA better
> integrate with reactive streams. I’m working on the API updates in a branch
> and will push that branch ASAP. At present this is strictly a idea under
> discussion as it is a substantial change and we won’t go down this path
> without more discussion from the wider community.
> The proposal is easy to describe though there are definitely some tricky
> bits in the actual API design.
>  - Replace Submission everywhere with java.util.concurrent.Flow.Publisher
>  - Replace ParameterizedOperation.set(String, CompletionStage, SqlType)
> with set(String, Publisher, SqlType)
>  - Make DataSource a Publisher<Session>
> That’s the core idea but there will be other changes. Effectively this
> replaces all uses of CompletionStage with Publisher. Not exactly because it
> also removes Submission as it is not needed.
> I have one small question. CompletionStage<Void> is ok. It is used to
> signal that an Operation completed with no result. Is Publisher<Void> ok? I
> assume that such a Publisher could only call onComplete or onError which is
> just what is needed for these use cases.

*James Roper*
*Senior Developer, Office of the CTO*

Lightbend <https://www.lightbend.com/> – Build reactive apps!
Twitter: @jroper <https://twitter.com/jroper>

More information about the jdbc-spec-discuss mailing list