zeromq / netmq

A 100% native C# implementation of ZeroMQ for .NET
Other
2.95k stars 744 forks source link

REQ-REP Pattern - Wait needed between ZSocket Send and PollIn or EFSM error #906

Closed grandangelo closed 4 years ago

grandangelo commented 4 years ago

Following lazy pirate pattern for .NET, it seems that I need to add a pause of at least 50 ms between ZSocket.Send and ZSocket.PollIn or I get a EFSM error.

I'm currently using libzmq version 4.1.0.31 on Windows 7 64bit.

Code extract:

ZError error = ZError.None;
string message = "message";

using (ZFrame outgoing = ZFrame.Create(message.Length))
{
    outgoing.Write(message);
    // _requester is a ZSocket previously created
    if (!_requester.Send(outgoing, out error))
    {
        if (error == ZError.ETERM)
            return;
        throw new ZException(error);
    }
}

Thread.Sleep(50); // Commenting this Sleep causes PollIn to raise EFSM error

if (_requester.PollIn(_poll, out ZMessage incoming, out error, timeout))
{
    // Process Message
}

Commenting Thread.Sleep causes the following PollIn to raise an EFSM error. I don't understand why it is happening. It seems to me that _requested.Send returns before having actually sent any message, and PollIn complains about receiving without having sent.

I'm not an expert at all, thanks for pointing me any error or suggestion.

somdoron commented 4 years ago

It is actually not NetMQ (CLRZMQ probably), but I will try to help anyway.

For lazy pirate to work, you got to recreate the REQ socket on every try. The other alternative is to enable the following socket options: ZMQ_REQ_CORRELATE ZMQ_REQ_RELAXED

grandangelo commented 4 years ago

@somdoron I tried with the socket options you suggested without any luck. What is disappointing me is that it seems that calls are not blocking, i.e. ZSocket.PollIn is executed before ZSocket.Send finishes its execution, I can't otherwise understand how it can raise a EFSM error. Socket recreation is done but not shown in code, but it does not fix my problem. I think I'm missing something about ZMQ functioning.

I was not aware of the difference between NetMQ and CLRZMQ, thanks for mentioning. I will try to see if something changes with NetMQ, or I will move to a pattern different from REQ-REP.

grandangelo commented 4 years ago

Server side was processing something with a given timeout. I was using the same timeout to get the answer from the client. So adding a delay was giving to the server enough time to answer me. So: no issue with Zero/Net MQ, just with myself :-)