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

Akka.IO & WSAEWOULDBLOCK socket error #3188

Closed
andreichuk opened this issue Nov 10, 2017 · 5 comments
Closed

Akka.IO & WSAEWOULDBLOCK socket error #3188

andreichuk opened this issue Nov 10, 2017 · 5 comments

Comments

@andreichuk
Copy link

Akka.NET version 1.3.2
Windows 10

Akka.IO does not handle non-fatal socket errors like WSAEWOULDBLOCK (System.Net.Sockets.SocketError.WouldBlock) which lead to closing of a connection.
From MSDN: Resource temporarily unavailable. This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a nonfatal error, and the operation should be retried later.

When I'm trying to send a large (1 Mb or more) amount of data over the wire, I split it in chunks ~64kb and send one by one:

  1. Get a chunk of data (if anything left)
  2. Send it to Akka.IO
  3. Receive an acknowledgement
  4. Go to 1.
    With default Akka.IO tcp settings sending a file from a client to a server (both localhost) usually fails after few cycles because a socket throws WSAEWOULDBLOCK socket exception. It looks like the acknowledgement is sent by Akka.IO when data has been added to the socket's send buffer, not when it's actually has been sent. So overflowing the send buffer leads to the error. Decreasing chunk size to ~10 Kb helps but there is no guarantee that:
    a) there is only one "chunk sender" on the client at the moment;
    b) the server is able read/process even those 10 Kb fast enough.

I checked this code. It does not catch any exceptions, just checks a number of bytes written. Maybe there should be a catcher for WSAEWOULDBLOCK that waits for N milliseconds and then call the method again? Or you have better ideas? Help is appreciated! :)

@Horusiath
Copy link
Contributor

Horusiath commented Nov 10, 2017

Some notes from talk about this feature in DotNetty (also see code examples: 1 and 2):

Basically it attempts sync ops and switches to async when it would block otherwise. Now that there's true support for sync completions in .net core it might make sense to forego sync path completely for writes.

@Horusiath
Copy link
Contributor

@andreichuk would you be able to give some reproducible example that could serve as a test scenario?

@andreichuk
Copy link
Author

andreichuk commented Nov 21, 2017

@andreichuk
Copy link
Author

@Aaronontheweb
Copy link
Member

Resolved via #3206

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

3 participants