> On Apr 29, 2020, at 11:15 AM, Tom Forbes <t...@tomforb.es> wrote:
> 
> What exactly would the issue be with this:
> 
> ```
> import functools
> from threading import Lock
> 
> def once(func):
>    sentinel = object()
>    cache = sentinel
>    lock = Lock()
> 
>    @functools.wraps(func)
>    def _wrapper():
>        nonlocal cache, lock, sentinel
>        if cache is sentinel:
>            with lock:
>                if cache is sentinel:
>                    cache = func()
>        return cache
> 
>    return _wrapper
> ```

This recipe is the best variant so far and gives us something concrete to talk 
about :-)

Benefits: Guarantees the wrapped function is not called more than once.
Restrictions:  Only works with zero argument functions.
Risks: Any reentrancy or recursion will result in deadlock.
Limitations: No instrumentation. No ability to reset or clear. Won't work 
across multiple processes.

It would be nice to look at some compelling use cases.  Off hand, I can't think 
of time when I would have used this decorator.  Also, I have a nagging worry 
that holding a non-reentrant lock across an arbitrary user defined function 
call is recipe for deadlocks.  That's why during code reviews we typically 
check every single use of Lock() to see if it should have been an RLock(), 
especially in big systems where GC, __del__, or weakref callbacks can trigger 
running any code at just about any time.


Raymond










_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/B32VKG5IPHKEL4Y7MP7WMQZXZYYWVT64/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to