bgamari / nanomsg-haskell

Haskell bindings to nanomsg
MIT License
25 stars 12 forks source link

nonblocking version of `send` #13

Open CGenie opened 2 months ago

CGenie commented 2 months ago

Hello,

I have a push/pull socket pair. When the pull socket is not bound, and the pushone tries to send, it is blocked. I see that even though underneath we call the nonblocking version, there is a loop that checks the return status and keeps looping. This is my proposed sendNonblocking patch: https://github.com/garganscript/nanomsg-haskell/commit/5868db564d7d3c4568ccd11c852292b834d26c55

bgamari commented 1 month ago

I am not keen on the proposed interface. It should be more obvious from the type whether the operation succeeded.

Moreover, if we are going to add a non-blocking send operation then we should also add a non-blocking receive.

CGenie commented 1 month ago

I think recv' in that module is nonblocking. My use case is non-symmetric, i.e. I want to send as fast as possible, without waiting, and block on receiving. From the docs (https://nanomsg.org/v0.1/nn_send.3.html) it seems that a negative number in c_nn_send means an error occurred.

In the original send function we just check if -1 was returned and then in throwErrorIfRetryMayBlock we check the error code and, if any of EAGAIN, EINTR, EWOULDBLOCK (the last one is not mentioned in nn_send documentation) errors occurred, we keep looping. Thing is, I don't like the looping and I don't mind some messages being dropped at the cost of fast sendNonblocking call. I don't mind having send like the original one, I just think that if there is some interface to a library, it's useful to add functions that are very thin wrappers without any logic, so that one can support more wild use cases than the library author predicted :)