twittner/zeromq-haskell — Issue #10: zeromq no block usage
Author: a-wild-tigger
Created: 2011-12-26 00:29:37+00:00
State: open

I'm having trouble understanding how to use the no block option. Documentation says: Send operation should be performed in non-blocking mode. If it cannot be performed immediatley an error will be thrown (errno is set to EAGAIN). However if we call it in a manner: "receive sub1 [NoBlock]", How are we to catch the EAgain signal, in the same thread, since receive still blocks, since the source shows that it uses: throwErrnoIfMinus1RetryMayBlock_, which checks if theres data and if there isn't will call the function wait', which blocks until data is available.

I've tried something like:

hackedReceive :: Socket a -> [Flag] -> IO (Maybe B.ByteString)
hackedReceive a flgs = do
result <- tryJust (\e -> if isFullErrorType (ioeGetErrorType e) then Just () else Nothing) (receive a flgs)
case result of
Left _err -> return Nothing
Right bs -> return $ Just bs

But, that doesn't work due to the previous issue. Unless I'm missing something obvious, is it possible to write a function like receive but along the following lines, which returns Maybe SB.ByteString, so that it is easy to represent the idea that there is no thing for the socket to receive currently.

import System.IO.Error (isFullErrorType, ioeGetErrorType)

receiveMaybe :: Socket a -> [Flag] -> IO (Maybe SB.ByteString)
receiveMaybe sock fls = bracket messageInit messageClose $ \m ->
onSocket "receive" sock $ \s -> do
result <- tryJust (\e -> if isFullErrorType (ioeGetErrorType e) then Just () else Nothing)
(throwErrnoIfMinus1_ "receive" $ c_zmq_recv s (msgPtr m) (combine (NoBlock : fls)))
case result of
Left _err -> return Nothing
Right _ -> do
data_ptr <- c_zmq_msg_data (msgPtr m)
size <- c_zmq_msg_size (msgPtr m)
fmap Just $ SB.packCStringLen (data_ptr, fromIntegral size)