I am trying to play with asyncio and websockets those days and I am having troubles to reach a specific behaviour.
Context: I am subscribing to two streams that return timestamps: The stream "block_timestamp" return timestamps regularly, around each 2 sec. The stream "mint_start" will only return one timestamp at random time with a timestamp in the future.
Goal: When the "mint_start" timestamp is superior or equal to the "block_timstamp" timestamp, I would like to execute an other function.
Below is the event listener that works correctly:
async def event_listener(id, params, queue):
async with websockets.connect(url) as ws:
await ws.send(json.dumps({"id": 1, "method": "eth_subscribe", "params": params}))
subscription_response = await ws.recv()
subscription_response = json.loads(subscription_response)
if subscription_response.get("error"):
return subscription_response["error"]["code"], subscription_response["error"]["message"]
else:
print(f"Subscribed with success to stream id: {subscription_response['result']}")
while True:
message = await ws.recv()
await queue.put((id, message))
Here is the function that manage the timestamp returned by the two stream.
async def on_message(queue):
while True:
id, value = await queue.get()
if id == "block_timestamp":
block_timestamp = (json.loads(value)['params']['result']["timestamp"])
else:
start_mint = (decode_single('(uint112,uint112)', bytearray.fromhex(value['params']['result']['data'][2:])))
if start_mint >= block_timestamp:
# execute function
And finally the main function that run the two streams and the message handler concurently:
async def main():
params1 = ["newHeads"]
params2 = ["logs", {"address": ["0xf4003f4efbe8691b60249e6afbd307abe7758adb"],
"topics": [Web3.keccak(text="Sync(uint112,uint112)").hex()]}]
queue = asyncio.Queue()
await asyncio.gather(
event_listener("block_timestamp", params1, queue),
event_listener("mint_start", params2, queue),
on_message(queue)
)
def run():
asyncio.run(main())
When a specific condition is meet at on_message function level: start_mint >= block_timestamp, I would like to execute an other function. I would like to properly close the websocket and loop event that is running.
However so far I have no clue how to manage this correctly.
Thanks for the help