[Python-ideas] Enabling Event.set to notify all waiters with an exception

Pau Freixes pfreixes at gmail.com
Tue Jul 18 17:33:00 EDT 2017


Morning guys,

I came across with that idea trying to resolve a typical dogpile
pattern [1], having many DNS calls to the same domain because of a
miss in a DNS cache.

The usage of the the set either to notify that the waiters could be
awake and get the result from the cache or use it to notify that
something was wrong helped me to reduce the complexity of the code.
Just as an example:

 ```
if key in throttle_dns_events:
    yield from throttle_dns_events[key].wait()
else:
    throttle_dns_events[key] = Event(loop=loop)
    try:
        addrs = yield from \
            resolver.resolve(host, port, family=family)
        cached_hosts.add(key, addrs)
        throttle_dns_events[key].set()
    except Exception as e:
        # any DNS exception, independently of the implementation
        # is set for the waiters to raise the same exception.
        throttle_dns_events[key].set(exc=e)
        raise
    finally:
        throttle_dns_events.pop(key)
```

Any error caught by the locker will be broadcasted to the waiters. For
example, a invalid hostname.

I tried to open a PR to the CPython implementation, and they claim
that the current interface of all of the locks objects behind the
asyncio.locks [2] module try to keep the same interface as the
threading one [3]. Therefore, to modify the asyncio implementation
would need first a change in the threading interface.

I was determined to justify that change, but after a bit research, I
didn't find any example in other languages such as Java [4], C# [5] or
C++ [6]  allowing you to send an exception as a signal value to wake
up the sleeping threads.

is that enough to give up? I'm still reticent, I believe that this
simple change in the interface can help reducing the complexity to
handle errors in some scenarios.

I would like to gather more ideas, thoughts, and comments from you
about how can I still justify this change ...

Thanks,

[1] https://github.com/pfreixes/aiohttp/blob/throttle_dns_requests/aiohttp/connector.py#L678
[2] https://docs.python.org/3/library/asyncio-sync.html
[3] https://docs.python.org/3/library/threading.html
[4] https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#notifyAll()
[5] https://msdn.microsoft.com/en-us/library/system.threading.monitor.pulseall.aspx
[6] http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all

-- 
--pau


More information about the Python-ideas mailing list