| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
A test for making sure that interruption works would be great to have |
Sorry, something went wrong.
|
Looks good! |
Sorry, something went wrong.
| proactor.set_loop(self) | ||
| self._make_self_pipe() | ||
| self_no = self._csock.fileno() | ||
| if isinstance(self_no, int): |
There was a problem hiding this comment.
I'm curious when fileno() doesn't return int?
Especially taking into account that self._csock is created by asyncio itself, it is not a user-provided object.
Sorry, something went wrong.
There was a problem hiding this comment.
I saw this happening when _csock was mocked.
Sorry, something went wrong.
There was a problem hiding this comment.
We can fix all mocks from asyncio test suite and don't care if a third-party library will use mocking incorrectly,
Sorry, something went wrong.
|
Yes, I'll take a look at CI failures during the weekend - looks odd since all tests were passing locally. >>> import asyncio >>> l = asyncio.get_event_loop() # ProactorEventLoop() >>> l.run_forever() # at this point everything is stuck # press ctrl-c to break out of `run_forever` - works >>> l.run_forever() # run it again using the same loop # press ctrl-c again - now it does not work because proactor does not receive anything from the self socket I'm not sure how important is this use-case and what are general expectations for the internal state of event loop after breaking out of run_forever but first impression of this behavior - "it does not look right". I think a better option would be instead of relying on default handler of SIGINT we need to set custom handler that will record the fact of receiving ctrl-c and raise KeyboardInterrupt at some well defined point. |
Sorry, something went wrong.
|
Selector based loops use the same technique for waking a loop. |
Sorry, something went wrong.
|
Proactor loop does it as well - it schedules reading when self pipe is created. _loop_self_reading will get the future from the recv method of the proactor and subscribe for a completion of the future. Once data is received - _loop_self_reading will call recv and repeat everything.
|
Sorry, something went wrong.
|
Thanks for the explanation. Changing signal handlers is not an option for this particular pull request. I have a feeling that if we change signal handler for one loop implementation -- we should do it for all others. I see a motivation for handling interruption signals differently but the change is a subject for another discussion. The second option can work. |
Sorry, something went wrong.
|
in last update I've wrapped call to run_forever into try/except that:
|
Sorry, something went wrong.
|
@asvetlov please let me know if there is anything else that needs to be addressed. |
Sorry, something went wrong.
|
I still recommend removing isinstance(fd, int) check and fix all mocks in asyncio test suite if needed. |
Sorry, something went wrong.
|
will do |
Sorry, something went wrong.
| # and self-reading routine is not hooked up now and needs | ||
| # to be restarted | ||
| if (self._self_reading_future is not None and | ||
| self._self_reading_future.cancelled()): |
There was a problem hiding this comment.
Please replace .cancelled() with .done().
Interruption can occur when the recv() called fut.set_result() but before loop._loop_self_reading() callback executed on the next loop iteration.
Sorry, something went wrong.
| self._self_reading_future = None | ||
| self.call_soon(self._loop_self_reading) | ||
| super().run_forever() | ||
| except KeyboardInterrupt: |
There was a problem hiding this comment.
Replace except with finally.
Canceling self-reading doesn't make harm if run_forever() was stopped by another exception (or just normal execution finishing).
We will re-schedule self-reading again on next run_forever() call.
Sorry, something went wrong.
|
Or even better:
def run_forever(self):
assert self._self_reading_future is None
try:
super().run_forever()
finally:
if self._self_reading_future is not None:
self._self_reading_future.cancel()
self._self_reading_future = None
What do you think? |
Sorry, something went wrong.
|
I think looks plausible if we add call_soon before the super().run_forever(), otherwise nobody will read the data from the self socket. |
Sorry, something went wrong.
…l self_reading_future afterwards
|
Excellent! |
Sorry, something went wrong.
|
@asvetlov: Please replace # with GH- in the commit message next time. Thanks! |
Sorry, something went wrong.
|
This change broke the AMD64 Windows7 SP1 3.x builder (https://buildbot.python.org/all/#/builders/40). Note that this builder runs as a service so no console is attached. |
Sorry, something went wrong.
|
Seems related but different error on x86 Windows7 3.x (https://buildbot.python.org/all/#/builders/58). Both builders are running on Windows 7, which may make a difference as well. |
Sorry, something went wrong.
|
will take a look |
Sorry, something went wrong.
|
I think #11274 should address the issue.
|
Sorry, something went wrong.
|
Got my hands on Win7 VM, reproduced the issue and verified that it is fixed by #11274 |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
When wakeup fd is set - receiving the signal will also write its number to a fd. This in turn will unblock the proactor and allow to process pending signal handler.
Is this approach valid in general and if yes - what is the best way to test changes like this? // cc @asvetlov
https://bugs.python.org/issue23057