Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce to Reactive Messaging and Reactive Streams ? #20

Open
3 tasks
bsideup opened this issue Mar 6, 2018 · 18 comments
Open
3 tasks

Introduce to Reactive Messaging and Reactive Streams ? #20

bsideup opened this issue Mar 6, 2018 · 18 comments

Comments

@bsideup
Copy link

bsideup commented Mar 6, 2018

Hi!

Given the rising popularity of reactive APIs (also the Flow API in Java 9), such initiative as OpenMessaging should provide the first-class APIs for the reactive world.

To define the "reactive":

  • Standard Publisher/Subscriber API - should be compatible with http://www.reactive-streams.org, so that many existing reactive solutions can easily integrate (RxJava, Akka, Reactor, etc...)
  • Push/pull model - at least on end-user API level
  • Back-pressure awareness - clients should be able to request their demand and producers should respect it
  • [?] Smart resources utilization - ThreadPool-ing, async, non-blocking API

I pre-checked some of the points I think already provided. So far

The proven beauty of reactive APIs is that you can easily convert them to pull/push/streaming APIs, but not the other way around.
That might serve a foundation for the underlying implementations, but it's important to have it as an API, not the detail of implementation.

@zhouxinyu
Copy link
Member

Hi thanks for your advice, we may consider providing reactive APIs in openmessaging, but we need more research and discussions.
Currently, we are focusing on spec doc, message model, and non-reactive APIs, any advice is welcome.

@vongosling
Copy link
Collaborator

@bsideup Do you have any suggestion for reactive API style, I think it is a high-levelAPI base on our core API now.

@bsideup
Copy link
Author

bsideup commented Mar 28, 2018

@vongosling I don't think that the reactive APIs can be efficiently implemented on top of the APIs you have atm.

Reactive style has a concept of a dynamic "demand" known upfront.
The closest is StreamingConsumer but it doesn't support the demand, means that the consumer will inefficiency predict the demand and will not be able to react on back-pressure (i.e. loading 10 messages instead of 1000 because the consumer can only consume 10 messages per second)

@vongosling vongosling added this to the 1.1.0 milestone Sep 4, 2018
@harrycodawang
Copy link

@vongosling I don't think that the reactive APIs can be efficiently implemented on top of the APIs you have atm.

Reactive style has a concept of a dynamic "demand" known upfront.
The closest is StreamingConsumer but it doesn't support the demand, means that the consumer will inefficiency predict the demand and will not be able to react on back-pressure (i.e. loading 10 messages instead of 1000 because the consumer can only consume 10 messages per second)

We may consider integrating RSocket to OpenMessaging. What do you say?

@bsideup
Copy link
Author

bsideup commented Jan 16, 2019

@harrycodawang
I think that's a great idea and I'm happy to answer your questions about RSocket if you have any 👍

RSocket fits incredibly well into this story and I already had a very successful experience integrating it into an event gateway:
https://github.com/bsideup/liiklus

@vongosling
Copy link
Collaborator

@bsideup @harrycodawang very glad that we could pick up the topic about Reactive Streams :-) RSocket may not be an API level, I am not sure what's your point about here.Also, I have talked about with the micro-profile team from the Eclipse Foundation, who have tried a little bit in here, We could try to define and keep discussing.

@bsideup
Copy link
Author

bsideup commented Jan 16, 2019

@vongosling RSocket alone may not be, but RSocket RPC provides gRPC-like APIs (also defined as Protobuf services) with the back-pressure support and other nice features

@harrycodawang
Copy link

@bsideup Do you any thoughts that can be illustrated by some charts how RSocket can be integrated to OpenMessaging?

Thanks for referring to the project liiklus, could you please help share some illustration about the system architecture with RSocket, liiklus and Event Brokers? One of the questions in my head is that "Does it mean two network connections i.e. a RSocket connection plus a Broker Client/Server connection? Or we can use RSocket to implement the Broker Client/Server protocol, since as you said, reactive APIs have the most expressive foundation to implement all the APIs "

@bsideup
Copy link
Author

bsideup commented Jan 17, 2019

@harrycodawang

Do you any thoughts that can be illustrated by some charts how RSocket can be integrated to OpenMessaging?

I do, I can draft a simple RSocket RPC example for the OpenMessaging API

"Does it mean two network connections i.e. a RSocket connection plus a Broker Client/Server connection? Or we can use RSocket to implement the Broker Client/Server protocol, since as you said, reactive APIs have the most expressive foundation to implement all the APIs "

An RSocket connection is sufficient to cover the Broker Client/Server protocol.
Think about it as a "TCP with item flow control, not just bytes".

could you please help share some illustration about the system architecture with RSocket, liiklus and Event Brokers

Ok, I'll add it to Liiklus' description to help understand it better.
Basically, Liiklus to Event systems is what API Gateway (let's say, Nginx) to Http servers

@harrycodawang
Copy link

@bsideup

Ok, I'll add it to Liiklus' description to help understand it better.
Basically, Liiklus to Event systems is what API Gateway (let's say, Nginx) to Http servers
Yah, that is the question in my head.
In the API Gateway/Nignx case, usually the gateway is transforming the protocols or proxy packages between two connections. So if mapped to Liiklus case, that may mean a RSocket server acting as a broker Client. Let's say it's topology 1.
Or in another topology, RSocket connection is acting as the transport binding for the Broker Client/Server protocol. Let's say it's topology 2.
So Gateway illustrates topology 1 and TCP illustrates topology 1, which makes me a little confused.
But anyway, RSocket can also be a proxy, in which case RSocket is wrapping the Broker client, right?

@bsideup
Copy link
Author

bsideup commented Jan 18, 2019

@harrycodawang
I see where the confusion comes from. Sorry, I should have said that Liiklus could also be used as a non-transparent proxy with content modifications (e.g. encryption for GDPR), checks (e.g. JSON Schema), re-routing, etc.

Currently, it looks like this:

                              /-(Kafka's native protocol, not reactive)--> Kafka
clients ==(RSocket)==> Liiklus -(Pulsar native protocol, async)------> Pulsar
                              \--(OpenMessaging's protocol adapter)--> Any OM broker

(Where = is RSocket, client's protocol, and - is brocker's specific protocols). if OM will add RSocket support (and other vendors will start using it :) ), it will look more like this:

clients ==(RSocket)==> Liiklus ==(OpenMessaging's RSocket)==> Any OM broker

So, even if the Event Systems will support RSocket, Liiklus will stay (although dramatically simplified on the "event store plugin" part, visualized on the diagram on the right side).
But it will improve the whole system because client's demand will be transparently delivered from the client to brokers (currently it is done by the event storage plugins, specific for each storage)

@vongosling
Copy link
Collaborator

vongosling commented Jan 18, 2019

I think we could combine the issue to address how to support reactive programming paradigms. I've seen a lot of guys(Microprofile Reactive Streams, Spring Reactor, RSocket, Akka Streams, JDK8&JDK9, RxJava and so on.) work hard in this area but none of them is fittable for messaging. So, It's really worth exploring. After all, building an API like this was not our original intention.

@vongosling
Copy link
Collaborator

@vesense we can keep talking about it in this thread:-)

@vongosling vongosling changed the title Reactive APIs Introduce to Reactive Messaging and Reactive Streams ? Jan 18, 2019
@harrycodawang
Copy link

@harrycodawang
I see where the confusion comes from. Sorry, I should have said that Liiklus could also be used as a non-transparent proxy with content modifications (e.g. encryption for GDPR), checks (e.g. JSON Schema), re-routing, etc.

Currently, it looks like this:

                              /-(Kafka's native protocol, not reactive)--> Kafka
clients ==(RSocket)==> Liiklus -(Pulsar native protocol, async)------> Pulsar
                              \--(OpenMessaging's protocol adapter)--> Any OM broker

(Where = is RSocket, client's protocol, and - is brocker's specific protocols). if OM will add RSocket support (and other vendors will start using it :) ), it will look more like this:

clients ==(RSocket)==> Liiklus ==(OpenMessaging's RSocket)==> Any OM broker

So, even if the Event Systems will support RSocket, Liiklus will stay (although dramatically simplified on the "event store plugin" part, visualized on the diagram on the right side).
But it will improve the whole system because client's demand will be transparently delivered from the client to brokers (currently it is done by the event storage plugins, specific for each storage)

Thanks a lot for your illustration. I have 2 thoughts about the RSocket and Message system.

  1. Currently, when we consider the flow topology for messaging or stream processing, it is usually a DAG, which have only 1 direction data flow, while the communication style for RSocket (which is P2P oriented) has 3 other flow topology styles which have 2-direction data flows. Do you have any idea how this 2-direction data flow can be mapped to a topology involving multiple tops (broker or routers)?
  2. The back-pressure feature should be intuitively applicable to the messaging and stream processing scenario. But when the backend messaging engine (or the storage in Liiklus) has no native back-pressure support, can we method to support the back-pressure in the Reactive gateway?

@vongosling
Copy link
Collaborator

Push model - at least on end-user API level

@bsideup Could you tell me why do you prefer to support push model. once we adopt it, back pressure must be taken seriously.

The back-pressure feature should be intuitively applicable to the messaging and stream processing scenario. But when the backend messaging engine (or the storage in Liiklus) has no native back-pressure support, can we method to support the back-pressure in the Reactive gateway?

@harrycodawang It is eay to support backpressure in Reactive gateway,such as onBackpressureError,onBackpressureLatest,onBackpressureDrop and onBackpressureBuffer. But it seems to no meaning for messaging backpressure in producer/publisher.

@vongosling
Copy link
Collaborator

@bsideup @harrycodawang Do we have any further discussion for reactive messaging :-)

Standard Publisher/Subscriber API - should be compatible with http://www.reactive-streams.org, so that many existing reactive solutions can easily integrate (RxJava, Akka, Reactor, etc...)

Actually speaking, I am not sure which is standard API, There currently exist two Reactive Streams APIs. The first is provided by http://www.reactive-streams.org/, and lives in the org.reactivestreams package. The second is provided by JDK9, and lives as inner interfaces of the java.util.concurrent.Flow class. Both APIs are identical in everything but namespace. But what's the solution if we could broader our language except java?

@harrycodawang
Copy link

@bsideup @harrycodawang Do we have any further discussion for reactive messaging :-)

Standard Publisher/Subscriber API - should be compatible with http://www.reactive-streams.org, so that many existing reactive solutions can easily integrate (RxJava, Akka, Reactor, etc...)

Actually speaking, I am not sure which is standard API, There currently exist two Reactive Streams APIs. The first is provided by http://www.reactive-streams.org/, and lives in the org.reactivestreams package. The second is provided by JDK9, and lives as inner interfaces of the java.util.concurrent.Flow class. Both APIs are identical in everything but namespace. But what's the solution if we could broader our language except java?

It looks like consider from Java application developer side, JDK9 Flow class should be the most effortless API.

@bsideup Do you know whether RSocket supports JDK9 reactive-stream API?

@bsideup
Copy link
Author

bsideup commented Jan 29, 2019

@vongosling

Could you tell me why do you prefer to support push model. once we adopt it, back pressure must be taken seriously.

Here I should have referred it more like a "push-pull" model, sorry. request(n) in Reactive Streams communicates the demand, and later the producer "pushes" up to n items.

It is eay to support backpressure in Reactive gateway,such as onBackpressureError,onBackpressureLatest,onBackpressureDrop and onBackpressureBuffer

The methods you mentioned are "reactions" to the back-pressure, not the "support".
Supporting back-pressure is more like "communicating the demand dynamically between producer and consumer"

Currently, when we consider the flow topology for messaging or stream processing, it is usually a DAG, which have only 1 direction data flow, while the communication style for RSocket (which is P2P oriented) has 3 other flow topology styles which have 2-direction data flows. Do you have any idea how this 2-direction data flow can be mapped to a topology involving multiple tops (broker or routers)?

While RSocket does support 4 different styles (fire & forget, request/response, stream, and bi-directional), you don't have to implement all of them. They share the same RSocket (think channel) and you can start multiple requests on the same RSocket.

There currently exist two Reactive Streams APIs. The first is provided by http://www.reactive-streams.org/, and lives in the org.reactivestreams package. The second is provided by JDK9

Flow is indeed a port of reactive-streams spec in the JDK, with the exactly same semantics. All reactive libraries on JVM support reactive-streams, some provide adapters for the Flow API (i.e. Project Reactor does, and RSocket uses Project Reactor inside)

But what's the solution if we could broader our language except java?

The reactive spec is language agnostic and shares the same semantics between implementations

@harrycodawang

It looks like consider from Java application developer side, JDK9 Flow class should be the most effortless API.

Actually, it is the least effortless :D See my previous comment + there are a lot of Java 8 users who can't use Java 9+ yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants