I'll jump in for Mark as Europe heads to sleep.
> > R2DBC will require a non-blocking connection pool. Currently we don’t have one. On a related note: Most JDBC pools are exposed through the DataSource API which is blocking.
>
> By blocking DataSource API you mean that when getConnection() is called by application code it'll wait/block until one connection is ready, right?
> I'm not sure what's a non-blocking connection pool is tho'. Do you refer to a pool with an API that would allow me to do something like Pool.tryBorrow(TimeUnit)?
Imagine an API `<T> T Pool.acquire(Duration)`. When a caller invokes `T t = pool.acquire(Duration.ofSeconds(5))` and no object is available, the thread that the caller is running in goes into a blocked state waiting on an object to be returned to the pool and provided to the caller. This thread cannot be used for (and its associated stack memory) cannot be used by any other actor in the JVM until acquisition or timeout. Now imagine an alternate API `<T> Mono<T> pool.acquire()`. When a caller invokes `Mono<T> t = pool.acquire()` this is guaranteed to return immediately with no opportunity for blocking. But the key here is that you get this `Mono<T>` which is a reactive type, not the T itself. In a reactive system you then _subscribe_ to that `Mono` so that at some indeterminate point in the future you can act on what it provides you; `t.map(t -> String.valueOf(t)).subscribe()`. While that closure is waiting for a T to be provided **it does not block a thread from being used**. It will be notified when a new object is available and act in an available thread at this time.
This is the key point, that while waiting, threads are not occupied.
> > leave execution (i.e. concurrency) up to the runtime.
> > leave resource scheduling to the runtime/platform
>
> You refer to "runtime" a few times. Just to clarify, what does runtime (or platform) mean in this context exactly? What does it mean to leave concurrency up to the runtime/ platform?
Imagine the following code from Project Reactor (a Reactive runtime):
```
Flux<Integer> odds = generator.odds();
Flux<Integer> evens = generator.evens();
Flux.merge(odds, evens)
.doOnNext(System.out::println)
.subscribe()
```
How many threads do you think are required to execute this merging of numbers in the most efficient way possible? Is it 1 where we drain all odds, then all evens? Is it 2 so that odds and evens are interleaved in a random order? If the generator retrieved odds via a web service and evens locally in the VM does that change your answer? This is what we mean by leaving concurrence and resource scheduling up to the runtime (Reactor). What we're *actually* saying is that `odds` and `evens` can be executed in parallel with one another and `System.out::println` must be executed sequentially after the generation. Beyond that, we don't care about threading models so long as we get the behavior and order we've declared.
```
odds evens
\ /
|
System.out::println
```
You'd be surprised exactly how sophisticated these reactive platforms are at determining scheduling. There's event loops, thread-stealing, micro-batching, and more. It's absolutely fascinating.
> > > R2DBC for Java is what the async SQL driver is for MSSQL?
> > Not sure I follow as I do not understand the question.
> What I meant is that if I'm right about the MSSQL driver being able to issue async (truly async) queries against a DB, then is R2DBC essentially the same thing for the Java world? (Hope this make more sense, if not, ignore it.)
Well, R2DBC is really an API for reactive (non-blocking, asynchronous, pull-push back pressure) access to _any database_ including MSSQL. Even in that Microsoft driver, the API describes asynchronicity (IAsyncResult), the implementation likely (but certainly not guaranteed) is non-blocking, and it doesn't include the third point, back pressure. At this time, Java doesn't have a spec that address any of the three and in this way .Net is ahead of us. We're going to jump beyond Microsoft with R2DBC.
Don't worry about being confused by reactive programming and why we focus on such obscure things like the distinctions between non-blocking, async, and reactive back pressure; it's tough for everyone to get started. In the mean time I highly recommend you check out Reactor's primer[1] for general (non R2DBC-specifc) reactive concepts.
-Ben
[1]:
https://projectreactor.io/docs/core/release/reference/#intro-reactive