Bugs in RedisCache Init and Serialization
Bug Description
I've encountered two bugs while using RedisCache:
-
The
is_connectedmethod: https://github.com/langflow-ai/langflow/blob/a97c29fb398a04b2e23a889627a5b30102782f3d/src/backend/base/langflow/services/cache/service.py#L222-L227 is called within an asynchronous method: https://github.com/langflow-ai/langflow/blob/a97c29fb398a04b2e23a889627a5b30102782f3d/src/backend/base/langflow/main.py#L105 When usingasyncio.run, it raises the error:RuntimeError: asyncio.run() cannot be called from a running event loop. -
Serialization error occurs for graphs and many outputs that are not of Message and Data component types, raising
TypeErrororPicklingError: https://github.com/langflow-ai/langflow/blob/a97c29fb398a04b2e23a889627a5b30102782f3d/src/backend/base/langflow/services/cache/service.py#L241-L250
Reproduction
-
Set Environment Variable:
- Configure the environment variable
LANGFLOW_CACHE_TYPEtoredis.
- Configure the environment variable
-
Start Application:
- Launch the application. This results in an error during
asyncio.run, specifically:RuntimeError: asyncio.run() cannot be called from a running event loop.
- Launch the application. This results in an error during
-
Modify Code:
- Remove or comment out the
is_connectedmethod call. - Execute any flow within the application. This leads to the following error:
TypeError: RedisCache only accepts values that can be pickled.
- Remove or comment out the
Expected behavior
-
The
RedisCacheshould initialize without raising errors. -
The
RedisCacheshould accept values without raising serialization errors, ensuring compatibility with various output types.
Who can help?
@italojohnny
Operating System
MacOS
Langflow Version
1.1.1
Python Version
None
Screenshot
No response
Flow File
No response
To address the issues with the RedisCache in Langflow version 1.1.1, you can make the following changes:
-
Fixing the
RuntimeErrorinis_connected: Avoid usingasyncio.run()within an already running event loop. Instead, check if the event loop is running and usecreate_taskorrun_until_completeaccordingly. Here's a modified version of theis_connectedmethod:def is_connected(self) -> bool: """Check if the Redis client is connected.""" import redis try: loop = asyncio.get_event_loop() if loop.is_running(): # If the loop is already running, use create_task task = loop.create_task(self._client.ping()) loop.run_until_complete(task) else: asyncio.run(self._client.ping()) except redis.exceptions.ConnectionError: logger.exception("RedisCache could not connect to the Redis server") return False return True -
Handling Serialization Issues: Ensure that only picklable objects are cached. Add a check before attempting to pickle the object in the
setmethod:@override async def set(self, key, value, lock=None) -> None: try: # Check if the value can be pickled pickle.dumps(value) if pickled := pickle.dumps(value): result = await self._client.setex(str(key), self.expiration_time, pickled) if not result: msg = "RedisCache could not set the value." raise ValueError(msg) except (TypeError, pickle.PicklingError) as exc: msg = "RedisCache only accepts values that can be pickled." raise TypeError(msg) from exc
These changes should help resolve the RuntimeError and serialization issues you are encountering with the RedisCache on MacOS [1].
To continue talking to Dosu, mention @dosu.
Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Other
I also saw this error with this simple setup:
- run docker langflow v1.1.1
- set LANGFLOW_REDIS_HOST or LANGFLOW_REDIS_URL
- set LANGFLOW_CACHE_TYPE to "redis"
Basically, when cache type is set to redis, the following error shows:
RuntimeError: asyncio.run() cannot be called from a running event loop.
Experiencing this in 1.1.3 as well. Although from looking at the codebase, this is going to be present in all versions. No idea how this was ever working in the first place.