Runs enqueued handlers until the channel is closed, or until the handler queue is empty once the channel is closed.
(self)
| 1415 | self._handler_thread.start() |
| 1416 | |
| 1417 | def _run_handlers(self): |
| 1418 | """Runs enqueued handlers until the channel is closed, or until the handler |
| 1419 | queue is empty once the channel is closed. |
| 1420 | """ |
| 1421 | |
| 1422 | while True: |
| 1423 | with self: |
| 1424 | closed = self._closed |
| 1425 | if closed: |
| 1426 | # Wait for the parser thread to wrap up and enqueue any remaining |
| 1427 | # handlers, if it is still running. |
| 1428 | self._parser_thread.join() |
| 1429 | # From this point on, _enqueue_handlers() can only get called |
| 1430 | # from Request.on_response(). |
| 1431 | |
| 1432 | with self: |
| 1433 | if not closed and not len(self._handler_queue): |
| 1434 | # Wait for something to process. |
| 1435 | self._handlers_enqueued.wait() |
| 1436 | |
| 1437 | # Make a snapshot before releasing the lock. |
| 1438 | handlers = self._handler_queue[:] |
| 1439 | del self._handler_queue[:] |
| 1440 | |
| 1441 | if closed and not len(handlers): |
| 1442 | # Nothing to process, channel is closed, and parser thread is |
| 1443 | # not running anymore - time to quit! If Request.on_response() |
| 1444 | # needs to call _enqueue_handlers() later, it will spin up |
| 1445 | # a new handler thread. |
| 1446 | self._handler_thread = None |
| 1447 | return |
| 1448 | |
| 1449 | for what, handler in handlers: |
| 1450 | # If the channel is closed, we don't want to process any more events |
| 1451 | # or requests - only responses and the final disconnect handler. This |
| 1452 | # is to guarantee that if a handler calls close() on its own channel, |
| 1453 | # the corresponding request or event is the last thing to be processed. |
| 1454 | if closed and handler in (Event._handle, Request._handle): |
| 1455 | continue |
| 1456 | |
| 1457 | with log.prefixed("/handling {0}/\n", what.describe()): |
| 1458 | try: |
| 1459 | handler() |
| 1460 | except Exception: |
| 1461 | # It's already logged by the handler, so just fail fast. |
| 1462 | self.close() |
| 1463 | os._exit(1) |
| 1464 | |
| 1465 | def _get_handler_for(self, type, name): |
| 1466 | """Returns the handler for a message of a given type.""" |