Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugs in RedisCache Init and Serialization #5303

Open
dhlidongming opened this issue Dec 17, 2024 · 1 comment
Open

Bugs in RedisCache Init and Serialization #5303

dhlidongming opened this issue Dec 17, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@dhlidongming
Copy link
Contributor

Bug Description

I've encountered two bugs while using RedisCache:

  1. The is_connected method:

    def is_connected(self) -> bool:
    """Check if the Redis client is connected."""
    import redis
    try:
    asyncio.run(self._client.ping())

    is called within an asynchronous method:
    await initialize_services(fix_migration=fix_migration)

    When using asyncio.run, it raises the error: RuntimeError: asyncio.run() cannot be called from a running event loop.

  2. Serialization error occurs for graphs and many outputs that are not of Message and Data component types, raising TypeError or PicklingError:

    async def set(self, key, value, lock=None) -> None:
    try:
    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 as exc:
    msg = "RedisCache only accepts values that can be pickled. "
    raise TypeError(msg) from exc

Reproduction

  1. Set Environment Variable:

    • Configure the environment variable LANGFLOW_CACHE_TYPE to redis.
  2. 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.
      
  3. Modify Code:

    • Remove or comment out the is_connected method call.
    • Execute any flow within the application. This leads to the following error:
      TypeError: RedisCache only accepts values that can be pickled.
      

Expected behavior

  1. The RedisCache should initialize without raising errors.

  2. The RedisCache should 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

@dhlidongming dhlidongming added the bug Something isn't working label Dec 17, 2024
Copy link

dosubot bot commented Dec 17, 2024

To address the issues with the RedisCache in Langflow version 1.1.1, you can make the following changes:

  1. Fixing the RuntimeError in is_connected:
    Avoid using asyncio.run() within an already running event loop. Instead, check if the event loop is running and use create_task or run_until_complete accordingly. Here's a modified version of the is_connected method:

    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
  2. Handling Serialization Issues:
    Ensure that only picklable objects are cached. Add a check before attempting to pickle the object in the set method:

    @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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant