Skip to content

feat: support passing existing Redis client to ISR handler#31

Closed
mrjasonroy wants to merge 1 commit intomainfrom
feat/pr23-existing-redis-client
Closed

feat: support passing existing Redis client to ISR handler#31
mrjasonroy wants to merge 1 commit intomainfrom
feat/pr23-existing-redis-client

Conversation

@mrjasonroy
Copy link
Owner

Summary

  • Allows RedisCacheHandler to accept a pre-existing ioredis client instance via the redis option
  • Uses duck typing instead of instanceof Redis to detect existing clients (avoids fragility across package versions/bundlers)
  • Tracks didCreateClient to skip error listeners and close() for shared clients
  • Added 5 tests covering existing client detection, lifecycle management, and error listener behavior

Based on #23 by @Antignote, reworked to address review feedback:

Supersedes #23

Test plan

  • All 95 unit tests pass (16 Redis handler tests, 5 new)
  • Existing client stores/retrieves values correctly
  • No error listener added for shared clients
  • Error listener added for internally created clients
  • close() skips shared clients, disconnects created clients
  • Lint, format, typecheck all pass

🤖 Generated with Claude Code

Allows RedisCacheHandler to accept a pre-existing ioredis client
instance, enabling connection reuse and custom configurations
(Cluster, Sentinel, etc.).

Key changes:
- Accept Redis instance via duck typing (avoids instanceof fragility)
- Track didCreateClient to skip error listeners for shared clients
- close() only disconnects internally-created clients
- Added 5 tests for existing client behavior

Based on #23 by @Antignote with improvements to the detection
mechanism and lifecycle management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link

Summary of Changes

Hello @mrjasonroy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the RedisCacheHandler by introducing the capability to utilize an already instantiated ioredis client. This change provides more control over Redis connection management, particularly in environments where a single Redis client might be shared across multiple components. The implementation focuses on robust client identification and careful resource handling to ensure that shared clients are not inadvertently closed or modified by the cache handler.

Highlights

  • Existing Redis Client Support: The RedisCacheHandler now accepts a pre-existing ioredis client instance via the redis option, allowing for greater flexibility in managing Redis connections.
  • Robust Client Detection: Client detection has been improved by using duck typing (checking for get, set, del methods) instead of instanceof Redis. This avoids fragility issues that can arise from different package versions or bundler setups.
  • Lifecycle Management: A new didCreateClient flag tracks whether the handler internally created the Redis client. This ensures that error listeners are only attached, and the close() method only calls quit(), for clients managed by the handler, preventing unintended side effects on shared client instances.
  • Comprehensive Testing: Five new tests were added to cover existing client detection, proper lifecycle management (error listeners and close() behavior), and ensure correct functionality when a shared client is provided.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • packages/cache-handler/src/handlers/redis.test.ts
    • Added quitCalled property and quit method to FakeRedis class to facilitate testing of client disconnection behavior.
    • Updated a comment for clarity regarding cache entry simulation.
    • Introduced a new test suite for 'existing Redis client support' with five new tests covering client acceptance, error listener behavior, and close() method functionality for both shared and internally created clients.
  • packages/cache-handler/src/handlers/redis.ts
    • Modified the RedisCacheHandlerOptions interface to allow the redis property to accept an existing ioredis client instance.
    • Updated JSDoc examples to illustrate how to pass an existing Redis client to the handler.
    • Refactored the constructor to implement duck typing for detecting existing Redis client instances, assigning them directly if found, and setting a didCreateClient flag accordingly.
    • Conditionalized the attachment of the Redis error listener, ensuring it is only added if the client was internally created by the handler.
    • Modified the close() method to conditionally call redis.quit(), ensuring that only internally created clients are disconnected, while shared clients remain active.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature by allowing an existing Redis client instance to be passed to the RedisCacheHandler. The implementation correctly uses duck typing to detect the client and manages the client's lifecycle (error listeners, closing connection) based on whether it was created internally or provided externally. The accompanying tests are comprehensive and validate the new behavior thoroughly. I have one suggestion to improve the robustness of the duck-typing check.

Comment on lines +110 to +115
options.redis &&
typeof options.redis === "object" &&
"get" in options.redis &&
"set" in options.redis &&
"del" in options.redis &&
typeof (options.redis as Redis).get === "function"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current duck-typing for an existing Redis client is not fully robust. It checks for the existence of get, set, and del properties, but only confirms that get is a function. This could lead to runtime errors if an object is passed where set or del are properties but not functions.

A more robust approach is to verify that all three methods (get, set, del) are indeed functions. This also simplifies the condition by making the in checks redundant.

      options.redis &&
      typeof options.redis === "object" &&
      typeof (options.redis as Redis).get === "function" &&
      typeof (options.redis as Redis).set === "function" &&
      typeof (options.redis as Redis).del === "function"

@mrjasonroy
Copy link
Owner Author

Closing in favor of pushing updates directly to #23

@mrjasonroy mrjasonroy closed this Feb 24, 2026
@mrjasonroy mrjasonroy deleted the feat/pr23-existing-redis-client branch February 24, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant