I currently have two infinite asynchronous tasks running and want to share state between them. One task is a websocket connection that reads in messages then sends messages and the other reads in incoming light data. I want to send a boolean between the two tasks that says whether or not the websocket connection is successful.
Here is how I'm initializing the context.
client_connect_var = contextvars.ContextVar('client_connect',default = False)
client_connect_var.set(False)
ctx = contextvars.copy_context()
async def main():
message = json.dumps({'payload': {
'payload'})
loop = asyncio.get_event_loop()
start_light = asyncio.create_task(calculate_idle(3))
await asyncio.gather(init_connection(message), start_light)
ctx.run(asyncio.run(main()))
Here is my code in my init_connection:
async def init_connection(message):
async with websockets.connect(uri) as websocket:
#This should set the global context variable to true
client_connect_var.set(True)
CLIENT_WS = websocket
client_connect = client_connect_var.get()
# send init message
await websocket.send(message)
print("Connection is open")
while client_connect:
await handleMessages(websocket, message)
await websocket.close()
Here is where it's trying to get the current state in the light code
async def calculate_idle(t):
orig_time = t
while True:
await asyncio.sleep(5)
#This should be true, but it's false
client_connect = client_connect_var.get()
await asyncio.sleep(5)
In calculate_idle, the variable in the context is still set to false. I'm not sure how to get it to be set to true from inside init_connection. I'd like to expand this to updating other values in state that are objects. Any help would be appreciated!
ContextVar
serves the purpose opposite of what you're trying to use it for: it's for data that is local to a task, something like a "task-local" global variable.
To share data between two tasks you can use normal Python sharing mechanisms, e.g. a global variable or an ordinary mutable value (e.g. a dict or an instance of a class of your choosing). You can also use synchronization like asyncio.Event
(https://docs.python.org/3/library/asyncio-sync.html#asyncio.Event) to notify the other task when the value changes.