I previously asked how to run several autobahn.ApplicationSession instances from within the same python process, without having them block. The issue was resolved, however I've encountered a new issue. Terminating these mp.Process instances proves difficult. I know the code in ApplicationRunner.run() exits upon a KeyboardInterrupt, but I've been unable to get this to trigger correctly. Sample Code: class PoloniexSession(ApplicationSession): @coroutine def onJoin(self, *args, **kwargs): channel = self.config.extra['channel'] def onTicker(*args, **kwargs): self.config.extra['queue'].put((channel, (args, kwargs, time.time()))) try: yield from self.subscribe(onTicker, self.config.extra['channel']) except Exception as e: raise class PlnxEndpoint(mp.Process): def __init__(self, endpoint, q, **kwargs): super(PlnxEndpoint, self).__init__(name='%s Endpoint Process' % endpoint, **kwargs) self.endpoint = endpoint self.q = q def run(self): self.runner = ApplicationRunner("wss://api.poloniex.com:443", 'realm1', extra={'channel': self.endpoint, 'queue': self.q}) self.runner.run(PoloniexSession) def join(self, *args, **kwargs): def sig_handler(x, y): pass signal.signal(signal.SIGINT, sig_handler) super(PlnxEndpoint, self).join(*args, **kwargs) class PoloniexWSS(WSSAPI): def __init__(self, endpoints=None): super(PoloniexWSS, self).__init__(None, 'Poloniex') self.data_q = mp.Queue() self.connections = {} if endpoints: self.endpoints = endpoints else: r = requests.get('https://poloniex.com/public?command=returnTicker') self.endpoints = list(r.json().keys()) self.endpoints.append('ticker') for endpoint in self.endpoints: self.connections[endpoint] = PlnxEndpoint(endpoint, self.data_q) def start(self): super(PoloniexWSS, self).start() for conn in self.connections: self.connections[conn].start() def stop(self): for conn in self.connections: self.connections[conn].join() super(PoloniexWSS, self).stop() While this fills self.q adequately, I still receive an error when my subprocesses are stopped: RuntimeError: Event loop stopped before Future completed. Traceback (most recent call last): File "/home/nils/anaconda3/lib/python3.5/multiprocessing /process.py", line 254, in _bootstrap self.run() File "/home/nils/git/tools/bitexwss/bitexws//api/poloniex.py", line 46, in run self.runner.run(PoloniexSession) File "/home/nils/anaconda3/lib/python3.5/site-packages/autobahn-0.14.1-py3.5.egg/autobahn/asyncio/wamp.py", line 172, in run loop.run_until_complete(protocol._session.leave()) File "/home/nils/anaconda3/lib/python3.5/asyncio/base_events.py", line 335, in run_until_complete raise RuntimeError('Event loop stopped before Future completed.') Which leads me to believe my signal.SIGINT isn't triggered where I want it to. According to the source code of ApplicationRunner.run(), a SIGINT / KeyboardInterrupt should gracefully result in ending the serve_forever() method. Manually closing the asyncio.event_loop results in the above error as well: class PlnxEndpoint(mp.Process): #... def join(self, *args, **kwargs): loop = get_event_loop() loop.stop() super(PlnxEndpoint, self).join(*args, **kwargs) #... Continue reading...