| 
12 | 12 | import multiprocessing  | 
13 | 13 | import logging  | 
14 | 14 | import re  | 
 | 15 | +import signal  | 
15 | 16 | import pprint  | 
16 | 17 | import uuid  | 
17 | 18 | import traceback  | 
@@ -285,9 +286,19 @@ def status(self):  | 
285 | 286 |                         serialized_aggs[node_id][aggname] = total_agg.as_dict()  | 
286 | 287 | 
 
  | 
287 | 288 |                 yield from self.child_pipe.coro_send(serialized_aggs)  | 
 | 289 | +            elif msg == 'exit':  | 
 | 290 | +                break  | 
288 | 291 |             else:  | 
289 | 292 |                 print('evloop: unknown message')  | 
290 | 293 | 
 
  | 
 | 294 | +        # End of work. Wait for tasks and stop event loop.  | 
 | 295 | +        self.running = False # mark for other coroutines to exit  | 
 | 296 | +        tasks = [t for t in asyncio.Task.all_tasks() if t is not asyncio.Task.current_task()]  | 
 | 297 | +        yield from asyncio.gather(*tasks)  | 
 | 298 | + | 
 | 299 | +        self.loop.stop()  | 
 | 300 | + | 
 | 301 | + | 
291 | 302 |     @asyncio.coroutine  | 
292 | 303 |     def exec_tx(self, tx_block, node_id, aggname_prefix, conn_i):  | 
293 | 304 |         conn_name = "node_{}_{}_{}".format(node_id + 1, aggname_prefix, conn_i)  | 
@@ -359,7 +370,12 @@ def exec_tx(self, tx_block, node_id, aggname_prefix, conn_i):  | 
359 | 370 |                 # back to event loop and block it  | 
360 | 371 |                 yield from asyncio.sleep(0.5)  | 
361 | 372 | 
 
  | 
362 |  | -        print("We've count to infinity!")  | 
 | 373 | +        # Close connection during client termination  | 
 | 374 | +        # XXX: I tried to be polite and close the cursor beforehand, but it  | 
 | 375 | +        # sometimes gives 'close cannot be used while an asynchronous query  | 
 | 376 | +        # is underway'.  | 
 | 377 | +        if conn:  | 
 | 378 | +            conn.close()  | 
363 | 379 | 
 
  | 
364 | 380 |     @asyncio.coroutine  | 
365 | 381 |     def transfer_tx(self, conn, cur, agg, conn_i):  | 
@@ -407,14 +423,19 @@ def run(self):  | 
407 | 423 | 
 
  | 
408 | 424 |         for i, _ in enumerate(self.dsns):  | 
409 | 425 |             for j in range(1):  | 
410 |  | -                asyncio.ensure_future(self.exec_tx(self.transfer_tx, i, 'transfer', j))  | 
 | 426 | +                self.loop.create_task(self.exec_tx(self.transfer_tx, i, 'transfer', j))  | 
 | 427 | +            self.loop.create_task(self.exec_tx(self.total_tx, i, 'sumtotal', 0))  | 
411 | 428 |             asyncio.ensure_future(self.exec_tx(self.total_tx, i, 'sumtotal', 0))  | 
412 | 429 |             for j in range(10):  | 
413 |  | -                asyncio.ensure_future(self.exec_tx(self.insert_tx, i, 'inserter', j))  | 
 | 430 | +                self.loop.create_task(self.exec_tx(self.insert_tx, i, 'inserter', j))  | 
414 | 431 | 
 
  | 
415 |  | -        asyncio.ensure_future(self.status())  | 
 | 432 | +        self.loop.create_task(self.status())  | 
416 | 433 | 
 
  | 
417 |  | -        self.loop.run_forever()  | 
 | 434 | +        try:  | 
 | 435 | +            self.running = True  | 
 | 436 | +            self.loop.run_forever()  | 
 | 437 | +        finally:  | 
 | 438 | +             self.loop.close()  | 
418 | 439 | 
 
  | 
419 | 440 |     def bgrun(self):  | 
420 | 441 |         print('Starting evloop in different process')  | 
@@ -446,10 +467,9 @@ def clean_aggregates(self):  | 
446 | 467 |         print('aggregates cleaned')  | 
447 | 468 | 
 
  | 
448 | 469 |     def stop(self):  | 
449 |  | -        self.running = False  | 
450 |  | -        self.evloop_process.terminate()  | 
 | 470 | +        print('stopping client')  | 
 | 471 | +        self.parent_pipe.send('exit')  | 
451 | 472 |         self.evloop_process.join()  | 
452 |  | -        time.sleep(3)  | 
453 | 473 |         print('client stopped')  | 
454 | 474 | 
 
  | 
455 | 475 |     @classmethod  | 
 | 
0 commit comments