aiozmq
                                
                                
                                
                                    aiozmq copied to clipboard
                            
                            
                            
                        client not terminating on connection timeout
I have a question raised here on SO: http://stackoverflow.com/questions/38767067/python-program-not-exiting-on-exception-using-aiozmq which another user could reproduce.
Basically I am using rpc.connect_rpc with a timeout value. Once the timeout has exceeded, an exception is raised but the running program doesn't terminate. Details can be found from the aforementioned question.
Here is a small example to reproduce this issue:
import asyncio
from aiozmq import rpc
async def client():
    client = await rpc.connect_rpc(
        connect='tcp://127.0.0.1:5555',
        timeout=1)
    return await client.call.some_function()
loop = asyncio.get_event_loop()
loop.run_until_complete(client())  
This program hangs after raising a TimeoutError, with two extra non-python threads running  (zmq internal threads I would guess).  Catching the TimeoutError and closing the loop doesn't help.
@vxgmichel Out of curiosity, how did you determine that there are two extra non-python threads still running? As a more general question (or perhaps we should leave this for SO) how does this prevent the interpreter from dying?
@mentaal I simply used htop:
 PID  PRI   NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 5608 20   0  250M 20532  9592 S  0.4  0.5  0:00.24 │  │  └─ python3.5 test_aiozmq.py
 5610 20   0  250M 20532  9592 S  0.4  0.5  0:00.13 │  │     ├─ python3.5 test_aiozmq.py
 5609 20   0  250M 20532  9592 S  0.0  0.5  0:00.00 │  │     └─ python3.5 test_aiozmq.py
You already showed in your SO question that no extra python threads are running after the exception is raised.
I'm also stuck with this yesterday, after digging I found solution: http://api.zeromq.org/2-1%3azmq-setsockopt#toc15
For proper work, code should look like:
import asyncio
import aiozmq.rpc
import zmq
async def foo():
    client = await aiozmq.rpc.connect_rpc(connect="tcp://127.0.0.1:5555",
                                          timeout=1)
    client.transport.setsockopt(zmq.LINGER, 0)
    return await client.call.test()
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())
Don't really know is it too bad, but I vote for setting LINGER to 0 at initialization period, since 99% don't care about it. The main problem of this solution is that pyzmq behavior will differ from aiozmq behavior.