Represents an outgoing request, for which it is possible to wait for a response to be received, and register a response handler.
| 750 | |
| 751 | |
| 752 | class OutgoingRequest(Request): |
| 753 | """Represents an outgoing request, for which it is possible to wait for a |
| 754 | response to be received, and register a response handler. |
| 755 | """ |
| 756 | |
| 757 | _parse = _handle = None |
| 758 | |
| 759 | def __init__(self, channel, seq, command, arguments): |
| 760 | super().__init__(channel, seq, command, arguments) |
| 761 | self._response_handlers = [] |
| 762 | |
| 763 | def describe(self): |
| 764 | return f"{self.seq} request {json.repr(self.command)} to {self.channel}" |
| 765 | |
| 766 | def wait_for_response(self, raise_if_failed=True): |
| 767 | """Waits until a response is received for this request, records the Response |
| 768 | object for it in self.response, and returns response.body. |
| 769 | |
| 770 | If no response was received from the other party before the channel closed, |
| 771 | self.response is a synthesized Response with body=NoMoreMessages(). |
| 772 | |
| 773 | If raise_if_failed=True and response.success is False, raises response.body |
| 774 | instead of returning. |
| 775 | """ |
| 776 | |
| 777 | with self.channel: |
| 778 | while self.response is None: |
| 779 | self.channel._handlers_enqueued.wait() |
| 780 | |
| 781 | if raise_if_failed and not self.response.success: |
| 782 | raise self.response.body |
| 783 | return self.response.body |
| 784 | |
| 785 | def on_response(self, response_handler): |
| 786 | """Registers a handler to invoke when a response is received for this request. |
| 787 | The handler is invoked with Response as its sole argument. |
| 788 | |
| 789 | If response has already been received, invokes the handler immediately. |
| 790 | |
| 791 | It is guaranteed that self.response is set before the handler is invoked. |
| 792 | If no response was received from the other party before the channel closed, |
| 793 | self.response is a dummy Response with body=NoMoreMessages(). |
| 794 | |
| 795 | The handler is always invoked asynchronously on an unspecified background |
| 796 | thread - thus, the caller of on_response() can never be blocked or deadlocked |
| 797 | by the handler. |
| 798 | |
| 799 | No further incoming messages are processed until the handler returns, except for |
| 800 | responses to requests that have wait_for_response() invoked on them. |
| 801 | """ |
| 802 | |
| 803 | with self.channel: |
| 804 | self._response_handlers.append(response_handler) |
| 805 | self._enqueue_response_handlers() |
| 806 | |
| 807 | def _enqueue_response_handlers(self): |
| 808 | response = self.response |
| 809 | if response is None: |
no outgoing calls
no test coverage detected
searching dependent graphs…