Description
Often we want to maintain some state within a task during a computation, and have various other tasks interact with that state.
Currenlty our approach to handling this is to have long-running tasks that open up connections to other workers and communicate over queues, pub-sub, etc.. This works, but can be awkward, and is commonly a source of confusion even among advanced users.
I was playing with Ray recently and really enjoyed their new Actor model. I believe that we should shamelessly steal ideas from it :) (cc @robertnishihara)
User API
This involves creating a class
class Counter:
def __init__(self):
self.n = 0
def increment(self):
self.n += 1
def get_value(self):
return n
And then submitting this somehow to be an actor. Many API approaches here might be good. I'll do something dumb for now.
counter = client.submit_actor(Counter)
Functions on this class trigger something slightly lighter weight than a task
>>> counter.increment()
<ActorFuture ...>
>>> counter.get_value().result()
1
And this thing can be passed around to other tasks
def f(n, counter=None):
for i in n:
counter.increment()
futures = client.map(f, range(100), counter=counter)
Limitations
The introduction of state on a worker is powerful, but also limiting. Functionality would probably differ from tasks in the following way:
- Resilience would not be guaranteed. Eventually we might support checkpointing in various ways, but probably not to start.
- We wouldn't check in with the central scheduler, so these tasks wouldn't be recorded on the dashboard, used diagnosics, or load balanced in any way
Implementation
We might first enable workers to directly ask each other to execute tasks for them. No dependencies here, just "run this function for me please and hold onto the result until I or someone else asks for it".
ActorFutures would be like normal futures except that the scheduler would have no record of them, and they would also include the address of the worker on which they live and the ID of the actor to whom they belong.
We'll need to relax various validation checks that we use in testing to allow for this unexpected data to exist.