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

rcvtimeo values not honored by recv #198

Closed
caffeine-overload opened this issue Jan 15, 2020 · 6 comments
Closed

rcvtimeo values not honored by recv #198

caffeine-overload opened this issue Jan 15, 2020 · 6 comments

Comments

@caffeine-overload
Copy link

It seems like regardless of the value for rcvtimeo set, recv is waiting for a message for ever.

Example

With a local PUB socket already set up:

using ZMQ

s1 = Socket(SUB)
s1.rcvtimeo = 5000

connect(s1, "tcp://localhost:5000")
subscribe(s1, "HHHHH") # a topic that never gets published to
a = recv(s1, String)

Expected behavior

recv gives up after 5 seconds

Actual behavior

recv hangs

More info

Using Julia Version 1.1.0

Calling msg_recv without the ZMQ_DONTWAIT flag, i.e. requesting blocking mode from zeromq, results in desired behavior. Although obviously you then don't have the convenience functions like recv(socket::Socket, ::Type{T}).

Maybe having an optional argument in recv to not use the ZMQ_DONTWAIT flag could be a simple fix for the moment.

@vtjnash
Copy link
Contributor

vtjnash commented Jan 15, 2020

Duplicate of #87

@vtjnash
Copy link
Contributor

vtjnash commented Jan 15, 2020

I'm not sure what that field is for, but in general Julia is designed to give you synchronous options with lightweight Tasks so that you don't need to manage these timeouts manually.

@caffeine-overload
Copy link
Author

I'm not sure what that field is for

You mean ZMQ_DONTWAIT?

@vtjnash
Copy link
Contributor

vtjnash commented Jan 16, 2020

s1.rcvtimeo

@caffeine-overload
Copy link
Author

If ZMQ_DONTWAIT is not used, msg_recv will wait for up to rcvtimeo milliseconds for a message to arrive. If one doesn't, it will return and set the EAGAIN error.

Even if there is a way to emulate this in julia using tasks, I still think the functionality in zmq itself should be made available. I also don't believe Julia yet has a reliable way to terminate an overrunning task easily.

@caffeine-overload
Copy link
Author

I made my own function to suit my (very simple - just a script that receives and handles values - but I know that messages arrive at least every milliseconds, so a timeout indicates a dead connection) particular use case, I'm just leaving it here in case anyone else has a similar use case.

function zmq_receive(socket::ZMQ.Socket)::Union{String, Missing}
    zmsg = ZMQ.msg_init()
    status = ZMQ.msg_recv(socket, zmsg, 0)
    if status == -1
        if ZMQ.zmq_errno() == ZMQ.EAGAIN
            @warn "Socket timeout"
            return missing
        else
            throw(StateError(ZMQ.jl_zmq_error_str()))
        end
    end
    return ZMQ.unsafe_copy(String, zmsg)
end

This functions honors rcvtimeo, but probably will block a task without letting julia switch to a different one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants