shizmob / pydle

An IRCv3-compliant Python 3 IRC library.
BSD 3-Clause "New" or "Revised" License
154 stars 48 forks source link

Resolve Client.whois deadlock #112

Closed theunkn0wn1 closed 5 years ago

theunkn0wn1 commented 5 years ago

Resolves a deadlock that can occur in several blocking coroutines, and specifically closes #111

In the case of whois, Client.whois returns an incomplete future, which is then awaited. The problem enlies that in Client.handle_forever where it ultimately awaits Client.whois, which in turn awaits for Client.handle_forever to receive the whois data from the server.

Handle Forever -> low level handlers -> userland implementation-> whois -> Handle Forever

I have resolved this issue by decoupling the Client.on_raw event from Client.handle_forever, allowing it to execute independently. (through an asyncio task) This breaks the deadlock where whois depends on handle_forever which depends on whois.

A foreseeable downside to this may be that the client may process incoming messages out of order, but such is the nature of programming asynchronously.


This Pr also removes the cancellation of the handle_forever task during unexpected disconnection, as it seems to create a deadlock of its own with the above patch applied.

That all being said I am continuing to investigate to see if there is a better solution, I am not convinced decoupling the on_raw event handler is necessarily the best fix for this bug. Feedback is welcome.