Skip to content

Latest commit

 

History

History
93 lines (78 loc) · 3.19 KB

File metadata and controls

93 lines (78 loc) · 3.19 KB

redis-stack Handler example

Note

In this example, we assume that in your deployment, you have REDIS_URL environment variable set to the URL of your Redis instance. You can use any other way to set the URL.

See the redis-stack Handler documentation for more information and requirements for the Redis server.

Create a file called cache-handler.mjs next to your next.config.js with the following contents:

import { CacheHandler } from '@neshca/cache-handler';
import { getClientInfoTag } from '@neshca/cache-handler/helpers';
import createLruHandler from '@neshca/cache-handler/local-lru';
import createRedisHandler from '@neshca/cache-handler/redis-stack';
import { createClient } from 'redis';

CacheHandler.onCreation(async () => {
  let client;

  try {
    // Create a Redis client.
    client = createClient({
      url: process.env.REDIS_URL ?? 'redis://localhost:6379',
      clientInfoTag: getClientInfoTag(),
    });

    // Redis won't work without error handling. https://github.com/redis/node-redis?tab=readme-ov-file#events
    client.on('error', (error) => {
      if (typeof process.env.NEXT_PRIVATE_DEBUG_CACHE !== 'undefined') {
        // Use logging with caution in production. Redis will flood your logs. Hide it behind a flag.
        console.error('Redis client error:', error);
      }
    });
  } catch (error) {
    console.warn('Failed to create Redis client:', error);
  }

  if (client) {
    try {
      console.info('Connecting Redis client...');

      // Wait for the client to connect.
      // Caveat: This will block the server from starting until the client is connected.
      // And there is no timeout. Make your own timeout if needed.
      await client.connect();
      console.info('Redis client connected.');
    } catch (error) {
      console.warn('Failed to connect Redis client:', error);

      console.warn('Disconnecting the Redis client...');
      // Try to disconnect the client to stop it from reconnecting.
      client
        .disconnect()
        .then(() => {
          console.info('Redis client disconnected.');
        })
        .catch(() => {
          console.warn(
            'Failed to quit the Redis client after failing to connect.',
          );
        });
    }
  }

  /** @type {import("@neshca/cache-handler").Handler | null} */
  let handler;

  if (client?.isReady) {
    // Create the `redis-stack` Handler if the client is available and connected.
    handler = await createRedisHandler({
      client,
      keyPrefix: 'prefix:',
      timeoutMs: 1000,
    });
  } else {
    // Fallback to LRU handler if Redis client is not available.
    // The application will still work, but the cache will be in memory only and not shared.
    handler = createLruHandler();
    console.warn(
      'Falling back to LRU handler because Redis client is not available.',
    );
  }

  return {
    handlers: [handler],
  };
});

export default CacheHandler;

Ensure that the Redis instance is running when you build your Next.js app. If you can not ensure that, see how to disable the Handler during a build stage in the Building the App Without Redis Cache Connection section.