question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unexcepted outcome while using requestChannel

See original GitHub issue

Hell 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:closed
  • Created 4 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
OlegDokukacommented, Jun 1, 2019

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 as Publisher 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 a requestChannel 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 a Publisher which does not take into account whether the stream from the client is completed and that Publisher produces that many onNext 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 one onNext and produce immediately onComplete 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.

  1. Pay attention to your ServerController which implements Publisher( 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.
  2. Remember, everything is async, and you must pay additional care that you properly synchronize you pipeline (take a look at Processor paradigm. Reactor offers a few good implementations of it)
  3. Use end to end chaining, for example, use map in order to convert payload and then convert the same stream back as an output

Regards, Oleh

1reaction
klopfdrehcommented, Mar 18, 2020

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:

    private class RSocketImpl extends AbstractRSocket {
        @Override
        public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
            return Flux.from(payloads).doOnNext(payload -> {
                LOGGER.info("Received payload: [{}]", payload.getDataUtf8());
            }).map(payload -> serverController.processClientPayload(payload))
                    .subscribeOn(Schedulers.parallel());
        }
    }

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. 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

channel = [id: 0x7acf3f0c, L:/100.55.10.124:9042 ! R:/30.75 ...
When all threads are in use, some requests wait in a queue (pending). If the queue fills up, some requests are silently rejected...
Read more >
JSD reporting issues by channel - Jira - Atlassian Community
I can see the Channel in the issue detail view but it doesn't appear as. ... based on JQL queries, you can use...
Read more >
Re: LSAgent Cloud Relay error - Lansweeper Community
LSAgentLog errors with a 'The request channel timed out while waiting for a replay ... 2020-03-27 09:10:01,516 [7] ERROR An unexpected exception was...
Read more >
High blocked NTR count during increased workload on ...
Summary. During DSE startup or at busy periods, Native Transport Requests (NTR) are blocked and client connections fail.
Read more >
spring-integration/gateway.adoc at main - GitHub
The defaults in the preceding configuration are applied to all methods on the gateway ... public interface Cafe { @Gateway(requestChannel="orders") void ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found