codypiersall / pynng

Python bindings for Nanomsg Next Generation.
https://pynng.readthedocs.io
MIT License
268 stars 58 forks source link

Telnet'ing into port used by Req0/Rep0 causes a block #51

Closed kejtan closed 4 years ago

kejtan commented 4 years ago

Hi Cody, I have a very simple use case utilizing the Req0/Rep0 pattern (pynng 0.4.1 / python 3.6.3) shown below:

def reply():
    import pynng
    socket = pynng.Rep0()
    socket.listen("tcp://127.0.0.1:9935")

    while True:
        m = socket.recv()
        print(f"{m}")
        socket.send(b"world")

def request():
    import pynng

    socket = pynng.Req0()
    socket.dial("tcp://127.0.0.1:9935")

    count = 0
    while True:
        try:
            print("sending")
            socket.send(b"hello")
            m = socket.recv()
            print(m)
            count = count + 1
            print(f"count: {count}")
        except Exception as e:
            print(e)
            print("retrying")

Under normal circumstances, this works fine (i.e. start reply(), followed by request()).

However, I encountered an issue that I can't seem to resolve. The scenario can be repeated like so: 1) start reply() 2) telnet 127.0.0.1 9935. I get a response "SP1". Leave this telnet window open 3) start request() 4) request() is blocked at socket.send until I randomly enter ~8 characters in the telnet window @ 2. This is will result is a "Connection to host lost" message. 5) request() functions normally after NB: As long as the telnet is left in the state @ 2, the request @ 4 will block indefinitely which is a problem

Is there something that I am missing? A similar code in pyzmq works. Any help is deeply appreciated.

codypiersall commented 4 years ago

That's very interesting. Thanks for opening the issue.

My guess here is that the Rep0 socket is stuck waiting for a connection to finish initializing. I wonder if this can be reproduced using the C implementation of nng? Since pynng is really just delegating to nng, I suspect it is an issue in the underlying lib. If you feel comfortable making a C reproducer, that would be very helpful. Otherwise I'll see what I can come up with, which would probably not be until around Christmas time.

Related reading may be the scalability protocol RFCs, e.g. the tcp mapping one: https://github.com/nanomsg/nanomsg/blob/master/rfc/sp-tcp-mapping-01.txt.

kejtan commented 4 years ago

Thanks for your prompt reply. Just a feedback.

As per your suggestion. I cloned nng's C source (from https://github.com/nanomsg/nng.git on 12/5/2019) and built the library (Build environment: Visual Studio 15 2017; Configuration: win32 / static library / release). I then used the provided demo Rep0/Req0 code (nng/demo/reqrep/reqrep.c) as a test case. It seemed similar in principle to our earlier python test code. Upon running in the manner above, it works - i.e. telnet doesn't block. I shall attempt to build the dynamic library and retry. If you any further ideas, I would be more then happy to assist.

Updates: Just finished building and testing with the following - Build environment: Visual Studio 15 2017; Configuration: win32 / dynamic library / release. Works as well.

kejtan commented 4 years ago

Hi Cody, I managed to resolve this by building pynng package on my machine with Visual Studio 15 based on the latest nng code (@ 12/5/2019). Thanks for the pointers. Merry Christmas to you.