This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author aeros
Recipients aeros, bquinlan, gvanrossum, pitrou
Date 2020-02-16.07:38:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1581838685.03.0.542500965222.issue39645@roundup.psfhosted.org>
In-reply-to
Content
Based on the following python-ideas thread: https://mail.python.org/archives/list/python-ideas@python.org/thread/LMTQ2AI6A7UXEFVHRGHKWD33H24FGM6G/#ICJKHZ4BPIUMOPIT2TDTBIW2EH4CPNCP.

In the above ML thread, the author proposed adding a new cf.SerialExecutor class, which seems to be not a great fit for the standard library (based on the current state of the discussion, as of writing this). But, Guido mentioned the following:

> IOW I'm rather lukewarm about this -- even if you (Jonathan) have found use for it, I'm not sure how many other people would use it, so I doubt it's worth adding it to the stdlib. (The only thing the stdlib might grow could be a public API that makes implementing this feasible without overriding private methods.)

Specifically, the OPs proposal should be reasonably possible to implement (either just locally for themselves or a potential PyPI package) with a few minor additions to cf.Future's public API:

1) Add a means of *publicly* accessing the future's state (future._state) without going through the internal condition's RLock.

This would allow the developer to implement their own condition or other synchronization primitive to access the state of the future. IMO, this would best be implemented as a separate ``future.state()`` and ``future.set_state()``. 

2) Add a means of *publicly* accessing the future's result (future._result) without going through the internal condition's RLock.

This would be similar to the above, but since there's already a ``future.result()`` and ``future.set_result()``, I think it would be best implemented as an optional *sync* parameter that defaults to True. When set to False, it directly accesses future._result without the condition; when set to True, it has the current behavior. 

3) Add public global constants for the different possible future states: PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, and FINISHED. 

This would be useful to serve as a template of possible future states for custom implementations. I also find that ``fut.set_state(cf.RUNNING)`` looks better than ``fut.state("running")`` from an API design perspective. 

Optional addition: To make ``fut.state()`` and ``fut.set_state()`` more useful for general purposes, it could have a single *sync* boolean parameter (feel free to bikeshed over the name), which changes whether it directly accesses future._state or does so safely through the condition. Presumably, the documentation would explicitly state that with sync=False, the future's state will not be synchronized across separate threads or processes. This would also allow it to have the same API as ``future.result()`` and ``future.set_result()``.

Also, as for my own personal motivation in expanding upon the public API for cf.Future, I've found that directly accessing the state of the future can be incredibly useful for debugging purposes. I made significant use of it while implementing the new *cancel_futures* parameter for executor.shutdown(). But, since future._state is a private member, there's no guarantee that it will continue to behave the same or that it can be relied upon in the long-term. This may not be a huge concern for quick debugging sessions, but could easily result in breakage when used in logging or unit tests.
History
Date User Action Args
2020-02-16 07:38:05aerossetrecipients: + aeros, gvanrossum, bquinlan, pitrou
2020-02-16 07:38:05aerossetmessageid: <1581838685.03.0.542500965222.issue39645@roundup.psfhosted.org>
2020-02-16 07:38:05aeroslinkissue39645 messages
2020-02-16 07:38:04aeroscreate