Actor receive macros #79
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Motivation
Test Plan
Notes
Just some thoughts about the work here and some considerations that went into it. What I would like out of actors with respect to message handling in the long-term:
Behaviors
Ergonomics
Approach: Behavior Objects
It makes for a nice abstraction to model behaviors as objects that have a function that checks for message-type map and a function that does the processing. You can create these with macros to hide the ugly construction and then you can group and mix/match different behaviors together for composability.
How this approach lacks mostly has to due with the Rust borrow checker. You want each behavior to have mutable access to actor, but you can't capture this in a lambda. Further you can't pass in a
selfto the behavior of the actor type. So these limitations will add to an awkward API that macros wouldn't be able to fully hide.Approach: Function Pointers
Instead of composing individual functions, just allow the user to define multiple "receive" functions and then switch between them at runtime. The default could just use the "receive" function that is already part of the actor trait.
Implementation wise, we would just need to track the function pointer in the
CellStatewhere we already store actor state and the actor itself.The limitations again come down to Rust in particular. Function pointers are possible but, you can't take a function pointer to a method on a dyn trait. Also, the borrow checker again makes this a bit hard. We could use weak reference types, but those require the use of
unsafe, which I want to fully avoid in this project.