2022-06-21 08:37:37 -07:00
Antipattern: Accessing Global Variable in Tasks/Actors
======================================================
2021-06-17 19:56:44 +01:00
2022-06-21 08:37:37 -07:00
**TLDR:** Don't modify global variables in remote functions. Instead, encapsulate the global variables into actors.
2021-06-17 19:56:44 +01:00
2022-06-21 08:37:37 -07:00
Ray tasks and actors decorated by `` @ray.remote `` are running in
different processes that don’ t share the same address space as ray driver
(Python script that runs ray.init). That says if you define a global variable
and change the value inside a driver, changes are not reflected in the workers
(a.k.a tasks and actors).
2021-06-17 19:56:44 +01:00
Code example
------------
**Antipattern:**
.. code-block :: python
2022-06-21 08:37:37 -07:00
import ray
global_v = 3
2021-06-17 19:56:44 +01:00
@ray.remote
2022-06-21 08:37:37 -07:00
class A:
def f(self):
return global_v + 3
2021-06-17 19:56:44 +01:00
2022-06-21 08:37:37 -07:00
actor = A.remote()
global_v = 4
# This prints 6, not 7. It is because the value change of global_v inside a driver is not
# reflected to the actor because they are running in different processes.
print(ray.get(actor.f.remote()))
2021-06-17 19:56:44 +01:00
2022-06-21 08:37:37 -07:00
**Better approach:** Use an actor’ s instance variables to hold the global state that needs to be modified / accessed by multiple workers (tasks and actors).
2021-06-17 19:56:44 +01:00
.. code-block :: python
2022-06-21 08:37:37 -07:00
import ray
@ray.remote
class GlobalVarActor:
def __init__(self):
self.global_v = 3
def set_global_v(self, v):
self.global_v = v
def get_global_v(self):
return self.global_v
@ray.remote
class A:
def __init__(self, global_v_registry):
self.global_v_registry = global_v_registry
def f(self):
return ray.get(self.global_v_registry.get_global_v.remote()) + 3
global_v_registry = GlobalVarActor.remote()
actor = A.remote(global_v_registry)
ray.get(global_v_registry.set_global_v.remote(4))
# This will print 7 correctly.
print(ray.get(actor.f.remote()))
Notes
-----
Note that using class variables to update/manage state between instances
of the same class is not currently supported.
Each actor instance is instantiated across multiple processes,
so each actor will have its own copy of the class variables.