mgravell / Pipelines.Sockets.Unofficial

.NET managed sockets wrapper using the new "Pipelines" API
Other
417 stars 54 forks source link

[Question][SocketConnection] Why do I need to read to send data? #13

Closed aensidhe closed 6 years ago

aensidhe commented 6 years ago

Disclaimer: probably, in production code this will not be a problem.

I'm playing with library, trying to understand how to plug it in my code. I do basically this:

await SocketConnection().ConnectAsync();
await Read();
await Send();
await Flush();
await Read(); // <--- If I don't do this read, data from Send above probably will never be sent

Questions:

  1. Should I be worried about it?
  2. Do I use library in intended way?
mgravell commented 6 years ago

What makes you think you need to read for it to send? The send and receive pipes are completely separate (they're literally two different Pipe instances). Can you clarify what you are seeing?

mgravell commented 6 years ago

Did you perhaps dispose the pipe/socket before it could be sent?

aensidhe commented 6 years ago

I'm sorry for week of silence, work :)

I have server, that write to log such messages:

tarantool_1_9_1  | 2018-09-24 19:08:49.839 [1] main/116/main I> Connection. user=guest id=5
tarantool_1_9_1  | 2018-09-24 19:08:56.627 [1] main/117/main I> Authenticated user operator, status: true
tarantool_1_9_1  | 2018-09-24 19:08:56.627 [1] main/117/main I> Authentication attempt
tarantool_1_9_1  | 2018-09-24 19:09:01.030 [1] main/118/main I> Disconnection. user=operator id=5

First message is written when a connection established, second and third are when auth is done, last is when connection breaks.

When I use pipelines, 2nd and 3rd messages do not appear until I start to read from pipeline. I suggested that it is behaviour of server. It's quite handy that I have previous version of library, based on NetworkStream to test.

In previous library I disable reading from socket by commenting start of it and basically do same stuff as with pipelines:

  1. Connect.
  2. Manual read of server greeting, which contains salt for auth
  3. Forming package and send it server.

As the result I see all messages in log of server. Unfortunately, I can't explain this behaviour. I will try to create a bare minimum repo, if you're interested.

mgravell commented 6 years ago

I'm very interested. Repros are always the most useful tool here.

aensidhe commented 6 years ago

In case I'm missing something, I checked with wireshark and, until I call reading, packet with auth is not going anywhere, I can't see it in capture. Since I ruled out almost everything where I can be wrong, I'll start tomorrow with repro repo. It's too late now.

aensidhe commented 6 years ago

This is a repro repo

During building and poking with it I found that main problem was good debugger of Rider, which suspends all threads, it seems and this is why pipeline effectively stopped.

I was able to verify that any way to wait after flush will effectively "send" data through the code: either via thread context switch or simple big loop.

Sorry for bringing issue up, I should build repro repo first :)

mgravell commented 6 years ago

No problem - I'm glad you found your answer, and I found it an interesting journey. Any other problems: ping away!