[Python-ideas] Async API
Yury Selivanov
yselivanov.ml at gmail.com
Tue Oct 30 02:59:56 CET 2012
Guido, Greg,
On 2012-10-27, at 7:45 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> Right. But now I'm not sure this approach will work with yield-froms.
> As when you yield-fromming scheduler knows nothing about the chain of
> generators, as it's all hidden in the yield-from implementation.
I think I've come up with a solution that should work for yield-froms too
(if we accept my in_finally idea in 3.4). And there should be a way
of writing a 'protect_finally' context manager too.
I'll illustrate the approach on Guido's tulip micro-framework
(consider it a pseudo code to illustrate the idea):
class Interrupt(BaseException):
"""Should penetrate all try..excepts"""
def call_with_timeout(timeout, gen):
context.current_task._add_timeout(timeout, gen)
try:
return (yield from gen)
except Interrupt:
raise TimeoutError() from None
class Task:
def _add_timeout(timeout, gen):
self.eventloop.call_later(
timeout,
partial(self._interrupt, gen))
def _interrupt(self, gen):
if not gen.in_finally:
gen.throw(Interrupt, Interrupt(), None)
else:
# So we set a flag to watch for gen's in_finally value
# on each 'step' call. And when it's 0 - Task.step
# will call '_interrupt' again.
self._watch_finally(gen)
I defined a new function 'call_with_timeout', because tulip's 'with_timeout'
starts a new Task, whereas the former works in any generator inside the task.
So, after that you'd be able to do the following:
yield from call_with_timeout(1.0, something())
And something's 'finally' won't ever be aborted.
-
Yury
More information about the Python-ideas
mailing list