[Async-sig] Blog post: Timeouts and cancellation for humans

Chris Jerdonek chris.jerdonek at gmail.com
Sun Jan 14 08:11:51 EST 2018


On Sun, Jan 14, 2018 at 3:33 AM, Nathaniel Smith <njs at pobox.com> wrote:
> On Fri, Jan 12, 2018 at 4:17 AM, Chris Jerdonek
> <chris.jerdonek at gmail.com> wrote:
>> Say you have a complex operation that you want to be able to timeout
>> or cancel, but the process of cleanup / cancelling might also require
>> a certain amount of time that you'd want to allow time for (likely a
>> smaller time in normal circumstances). Then it seems like you'd want
>> to be able to allocate a separate timeout for the clean-up portion
>> (independent of the timeout allotted for the original operation).
>> ...
>
> You can get these semantics using the "shielding" feature, which the
> post discusses a bit later:
> ...
> However, I think this is probably a code smell.

I agree with this assessment. My sense was that shielding could
probably do it, but it seems like it could be brittle or more of a
kludge. It would be nice if the same primitive could be used to
accommodate this and other variations in addition to the normal case.
For example, a related variation might be if you wanted to let
yourself extend the timeout in response to certain actions or results.

The main idea that occurs to me is letting the cancel scope be
dynamic: the timeout could be allowed to change in response to certain
things. Something like that seems like it has the potential to be both
simple as well as general enough to accommodate lots of different
scenarios, including adjusting the timeout in response to entering a
clean-up phase. One good test would be whether shielding could be
implemented using such a primitive.

--Chris

> Like all code smells,
> there are probably cases where it's the right thing to do, but when
> you see it you should stop and think carefully. If you're writing code
> like this, then it means that there are multiple different layers in
> your code that are implementing timeout policies, that might end up
> fighting with each other. What if the caller really needs this to
> finish in 15 seconds? So if you have some way to move the timeout
> handling into the same layer, then I suspect that will make your
> program easier to understand and maintain. OTOH, if you decide you
> want it, the code above works :-). I'm not 100% sure here; I'd
> definitely be interested to hear about more use cases.
>
> One thing I've thought about that might help is adding a kind of "soft
> cancelled" state to the cancel scopes, inspired by the "graceful
> shutdown" mode that you'll often see in servers where you stop
> accepting new connections, then try to finish up old ones (with some
> time limit). So in this case you might mark 'do_some_stuff()' as being
> cancelled immediately when we entered the 'soft cancel' phase, but let
> the 'do_cleanup' code keep running until the grace period expired and
> the region was hard-cancelled. This idea isn't fully baked yet though.
> (There's some more mumbling about this at
> https://github.com/python-trio/trio/issues/147.)
>
> -n
>
> --
> Nathaniel J. Smith -- https://vorpus.org


More information about the Async-sig mailing list