Unexcepted outcome while using requestChannel
See original GitHub issueHell everyone,
first of all thanks a lot for the java implementation of RSocket. First some side notes:
RSocket version: 0.12.2-RC2 My example project: https://github.com/klopfdreh/rsocket_playground Scenario: requestChannel
My output looks like this:
Server:
d.k.r.playground.ServerController - Person added: {"name":"Jon","size":192,"age":11}
d.k.r.playground.ServerController - {"valid":true,"person":{"name":"Jon","size":192,"age":11}}
d.k.r.playground.ServerController - Person added: {"name":"Maria","size":170,"age":21}
Client:
d.k.r.playground.ClientController - {"name":"Jon","size":192,"age":11}
d.k.r.playground.ClientController - {"name":"Maria","size":170,"age":21}
d.k.r.playground.ClientController - {"valid":true,"person":{"name":"Jon","size":192,"age":11}}
The first two lines of the client are information that are going to be sent to the server. The last line is the response from server
The server receives both persons, but wraps only one into that PersonResponse object and sends it back to the client.
My expectation would be that the client receives another line with valid true for Maria.
To reproduce just checkout the project start ServerStarter as Java Application and afterwards start ClientStarter as Java Application.
Thanks for the help in advance.
Issue Analytics
- State:
- Created 4 years ago
- Comments:13 (6 by maintainers)
Top GitHub Comments
First of all - everything happens asynchronously and in your case concurrently (reactive streams have
requestN
behavior so there are no guarantees that this call will be done in the same thread asPublisher
was generated).The above statement leads to the fact that you are using inappropriate collection which is non-thread safe at all (you are lucky it worked at all);
Then, RSocket
requestChannel
sends the first payload along with type (kind of optimization) so you receive arequestChannel
invocation and once you subscribe to the given publisher (requestChannel
parameter) the first element will be stored to the list immediately. But, there are no guarantees the second element appears immediately. It could be produced a moment later (again - everything is async), but you have aPublisher
which does not take into account whether the stream from the client is completed and thatPublisher
produces that manyonNext
as many elements are in the queue at a moment of iterating. Since you have got only one for sure (happens before guarantees) you will observe one, produce oneonNext
and produce immediatelyonComplete
call. Of course, the late element from the client side will appear later, but it does not affect the output anyhow.That is why once you postpone subscription to your publisher until completion of the upstream, there will be a guarantee that all elements will be in the queue.
ServerController
which implementsPublisher
( which is incorrect implementation). If you are going to run your code against Reactive-Streams TCK you will see that lots of tests will fail.Processor
paradigm. Reactor offers a few good implementations of it)map
in order to convert payload and then convert the same stream back as an outputRegards, Oleh
Hey @OlegDokuka - it has been a long time since I opened this issue. I did some refactoring and changed the implementation on server side to look like:
In addition I removed the list and assumed that the handling of the payload is done within the processClientPayload method. (Like storage) This addresses point 1. / 3. For point 2. I have to take a deeper look into the Processor API. Any other hints on this - or is there something left opened on which I have to take a better look at?
Thanks a lot again for your help and good explanations!
Note: The output is also as expected, now. 😄