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.