logologo
Empezar
Manual
Desarrollo
Plugins
API
English
简体中文
日本語
한국어
Deutsch
Français
Español
Português
Русский
Italiano
Türkçe
Українська
Tiếng Việt
Bahasa Indonesia
ไทย
Polski
Nederlands
Čeština
العربية
עברית
हिन्दी
Svenska
Empezar
Manual
Desarrollo
Plugins
API
logologo

Inicio rápido

Resumen de desarrollo de plugins
Escribir el primer plugin
Estructura de directorios del proyecto

Desarrollo del lado del servidor

Visión general
Plugin
Colecciones
Operaciones de base de datos
Gestión de fuentes de datos
Gestión de recursos
Control de permisos (ACL)
Middleware
Caché
Evento
Contexto de solicitud
Migración (Script de actualización)
Registro (Logger)
Internacionalización (I18n)
Línea de comandos (Command)
Gestión de tareas programadas
Pruebas

Desarrollo del lado del cliente

Visión general
Plugin
Contexto
Enrutador (Router)
Control de permisos (ACL)
Gestión de fuentes de datos
Recurso
Solicitud
Estilos y temas
Registro (Logger)
Internacionalización (I18n)
Pruebas

Otros

Guía de actualización de plugins
Lista de idiomas
Gestión de dependencias
Compilación
Previous PageMiddleware
Next PageEvento
Aviso de traducción por IA

Esta documentación ha sido traducida automáticamente por IA.

#Caché

El módulo de caché de NocoBase se basa en node-cache-manager y ofrece funcionalidades de caché para el desarrollo de plugins. El sistema incluye dos tipos de caché integrados:

  • memory - Caché en memoria basado en lru-cache, proporcionado por node-cache-manager por defecto.
  • redis - Caché de Redis basado en node-cache-manager-redis-yet.

Puede extender y registrar más tipos de caché a través de la API.

#Uso básico

#app.cache

app.cache es la instancia de caché predeterminada a nivel de aplicación y puede usarla directamente.

// Establecer caché
await app.cache.set('key', 'value', { ttl: 3600 }); // Unidad TTL: segundos

// Obtener caché
const value = await app.cache.get('key');

// Eliminar caché
await this.app.cache.del('key');

#ctx.cache

En operaciones de middleware o de recursos, puede acceder al caché a través de ctx.cache.

async (ctx, next) => {
  let data = await ctx.cache.get('custom:data');
  if (!data) {
    // Caché no encontrado, obtener de la base de datos
    data = await this.getDataFromDatabase();
    // Almacenar en caché, válido por 1 hora
    await ctx.cache.set('custom:data', data, { ttl: 3600 });
  }
  await next();
}

#Crear caché personalizado

Si necesita crear una instancia de caché independiente (por ejemplo, con diferentes espacios de nombres o configuraciones), puede usar el método app.cacheManager.createCache().

import { Plugin } from '@nocobase/server';

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Crear una instancia de caché con prefijo
    const myCache = await this.app.cacheManager.createCache({
      name: 'myPlugin',
      prefix: 'plugin:cache:', // Todas las claves añadirán automáticamente este prefijo
      store: 'memory', // Usar caché en memoria, opcional, por defecto usa defaultStore
      max: 1000, // Número máximo de elementos en caché
    });

    await myCache.set('user:1', { name: 'John' });
    const user = await myCache.get('user:1');
  }
}

#Descripción de los parámetros de createCache

ParámetroTipoDescripción
namestringIdentificador único para el caché, obligatorio
prefixstringOpcional, prefijo para las claves de caché, usado para evitar conflictos de claves
storestringOpcional, identificador del tipo de store (como 'memory', 'redis'), por defecto usa defaultStore
[key: string]anyOtros elementos de configuración personalizados relacionados con el store

#Obtener caché creado

const myCache = this.app.cacheManager.getCache('myPlugin');

#Métodos básicos de caché

Las instancias de caché ofrecen una amplia variedad de métodos para operar con el caché, la mayoría de los cuales se heredan de node-cache-manager.

#get / set

// Establecer caché, con tiempo de expiración (unidad: segundos)
await cache.set('key', 'value', { ttl: 3600 });

// Obtener caché
const value = await cache.get('key');

#del / reset

// Eliminar una única clave
await cache.del('key');

// Vaciar todo el caché
await cache.reset();

#wrap

El método wrap() es una herramienta muy útil que primero intenta obtener datos del caché. Si el caché no se encuentra (cache miss), ejecuta la función y almacena el resultado en el caché.

const data = await cache.wrap('user:1', async () => {
  // Esta función solo se ejecuta si el caché no se encuentra
  return await this.fetchUserFromDatabase(1);
}, { ttl: 3600 });

#Operaciones en lote

// Establecer en lote
await cache.mset([
  ['key1', 'value1'],
  ['key2', 'value2'],
  ['key3', 'value3'],
], { ttl: 3600 });

// Obtener en lote
const values = await cache.mget(['key1', 'key2', 'key3']);

// Eliminar en lote
await cache.mdel(['key1', 'key2', 'key3']);

#keys / ttl

// Obtener todas las claves (nota: algunos stores podrían no soportarlo)
const allKeys = await cache.keys();

// Obtener el tiempo de vida restante (TTL) de una clave (unidad: segundos)
const remainingTTL = await cache.ttl('key');

#Uso avanzado

#wrapWithCondition

wrapWithCondition() es similar a wrap(), pero le permite decidir si usar el caché mediante condiciones.

const data = await cache.wrapWithCondition(
  'user:1',
  async () => {
    return await this.fetchUserFromDatabase(1);
  },
  {
    // Los parámetros externos controlan si se usa el resultado del caché
    useCache: true, // Si se establece en false, la función se ejecutará de nuevo incluso si existe caché

    // Decide si se debe almacenar en caché basándose en el resultado de los datos
    isCacheable: (value) => {
      // Por ejemplo: solo almacenar en caché los resultados exitosos
      return value && !value.error;
    },

    ttl: 3600,
  },
);

#Operaciones de caché de objetos

Cuando el contenido almacenado en caché es un objeto, puede usar los siguientes métodos para operar directamente con las propiedades del objeto, sin necesidad de obtener el objeto completo.

// Establecer una propiedad de un objeto
await cache.setValueInObject('user:1', 'name', 'John');
await cache.setValueInObject('user:1', 'age', 30);

// Obtener una propiedad de un objeto
const name = await cache.getValueInObject('user:1', 'name');

// Eliminar una propiedad de un objeto
await cache.delValueInObject('user:1', 'age');

#Registrar un Store personalizado

Si necesita usar otros tipos de caché (como Memcached, MongoDB, etc.), puede registrarlos a través de app.cacheManager.registerStore().

import { Plugin } from '@nocobase/server';
import { redisStore, RedisStore } from 'cache-manager-redis-yet';

export default class PluginCacheDemo extends Plugin {
  async load() {
    // Registrar el store de Redis (si el sistema aún no lo ha registrado)
    this.app.cacheManager.registerStore({
      name: 'redis',
      store: redisStore,
      close: async (redis: RedisStore) => {
        await redis.client.quit();
      },
      // Configuración de conexión de Redis
      url: 'redis://localhost:6379',
    });

    // Crear caché usando el store recién registrado
    const redisCache = await this.app.createCache({
      name: 'redisCache',
      store: 'redis',
      prefix: 'app:',
    });
  }
}

#Consideraciones

  1. Límites del caché en memoria: Al usar un store de memoria, preste atención a configurar un parámetro max razonable para evitar desbordamientos de memoria.
  2. Estrategia de invalidación de caché: Al actualizar datos, recuerde limpiar el caché relacionado para evitar datos obsoletos.
  3. Convenciones de nombres para claves: Se recomienda usar espacios de nombres y prefijos significativos, como module:resource:id.
  4. Configuración de TTL: Establezca el TTL de manera razonable según la frecuencia de actualización de los datos para equilibrar el rendimiento y la consistencia.
  5. Conexión a Redis: Al usar Redis, asegúrese de configurar correctamente los parámetros de conexión y las contraseñas en el entorno de producción.