This PR makes two main changes in order to reduce the likelihood of deadlocks occurring and to provide tools for fixing deadlocks once they're discovered.
The initial step of enqueuing a message now completes or fails synchronously. This means that code sending a message to an actor can choose to ignore the response to a message if the response isn't needed.
Message handlers that don't return a value do not send a response. This completely removes the possibility of deadlock when sending the corresponding message.
Notably, this PR does NOT remove the ability to have message handlers return a response, which means that it's still possible to deadlock two (or more) actors in the manner described in #9. However, such deadlocks can now at least be resolved by not awaiting the response after sending the initial message, meaning that deadlocks can now be fixed once they're discovered.
We may want to go further and fully remove messages responses if it still proves to be too easy to cause a deadlock, however my intuition is that the feature is too useful to not support; Accomplishing the same flow with one-way message passing (as is the common approach in other actor frameworks) is cumbersome and boilerplate-heavy, which undermines the whole point of thespian. I'll continue to evaluate the state of things and gather notes in #9.
Partially addresses the issue raised in #9.
This PR makes two main changes in order to reduce the likelihood of deadlocks occurring and to provide tools for fixing deadlocks once they're discovered.
Notably, this PR does NOT remove the ability to have message handlers return a response, which means that it's still possible to deadlock two (or more) actors in the manner described in #9. However, such deadlocks can now at least be resolved by not awaiting the response after sending the initial message, meaning that deadlocks can now be fixed once they're discovered.
We may want to go further and fully remove messages responses if it still proves to be too easy to cause a deadlock, however my intuition is that the feature is too useful to not support; Accomplishing the same flow with one-way message passing (as is the common approach in other actor frameworks) is cumbersome and boilerplate-heavy, which undermines the whole point of thespian. I'll continue to evaluate the state of things and gather notes in #9.