Spraxium logoSpraxium

Configuración y patrones

La configuración de schedule usa el patrón split-config con defineSchedule para un setup con tipado seguro. Aprende la referencia completa de ScheduleConfig, buenas prácticas y patrones comunes de jobs.

Patrón split config

Como otros plugins de Spraxium, el módulo schedule usa el patrón split config, donde la configuración vive en un archivo dedicado dentro del directorio config/. El helper defineSchedule ofrece tipado completo y autocompletado para todos los campos de configuración. Tu spraxium.config.ts principal referencia el archivo de configuración, manteniendo limpia la configuración raíz y aislada cada configuración de plugin.

Cada plugin tiene su propio archivo de configuración con sus propios tipos, y la configuración raíz simplemente los importa y compone. Así evitas terminar con un objeto de configuración monolítico mezclando ajustes de prefix, schedule y HTTP.

El framework descubre y carga automáticamente la configuración de schedule durante el bootstrap. No necesitas llamar manualmente ninguna función de registro. Solo exporta la configuración desde el archivo y referénciala en el arreglo de imports de tu configuración raíz.

import { defineSchedule } from '@spraxium/schedule';

export default defineSchedule({
  timezone: 'America/Sao_Paulo',
  defaultLockTtlMs: 30_000,
  disableAll: false,
});

Referencia de ScheduleConfig

La interfaz ScheduleConfig controla el comportamiento global de todos los jobs programados. La mayoría de los campos son opcionales y tienen valores por defecto razonables que funcionan para bots de un solo proceso.

CampoTipoPredeterminadoDescripción
driverScheduleDriverMemoryDriverDriver de lock para ejecución distribuida
timezonestringPredeterminado del sistemaZona horaria IANA para jobs cron
defaultLockTtlMsnumber30000TTL de lock por defecto en milisegundos para el driver
disableAllbooleanfalseDeshabilita globalmente todos los jobs (útil para mantenimiento)

Organización del proyecto

Los servicios de schedule son providers inyectables normales que registras en cualquier módulo. Un patrón común es crear un módulo dedicado de tasks que agrupe todos los jobs en segundo plano, pero también puedes colocar métodos decorados con schedule en servicios específicos de dominio. La elección depende de si tus jobs son transversales (como limpieza y sincronización) o están fuertemente acoplados a una funcionalidad concreta.

Para tareas transversales, un módulo centralizado de tasks mantiene todo organizado. Para tareas específicas de una funcionalidad, colocar el decorador de schedule en un método del servicio de la propia funcionalidad evita indirecciones innecesarias. Ambos enfoques son válidos y el framework los trata de forma idéntica.

project structure
schedule.config.ts
tasks.module.ts
cleanup.service.ts
sync.service.ts
status.service.ts
moderation.module.ts
warning-expiry.service.ts

Patrones comunes

Combinar varios tipos de job en un servicio

Un solo servicio puede tener métodos decorados con distintos tipos de job. Esto es útil cuando tareas relacionadas tienen requisitos temporales distintos pero comparten las mismas dependencias. El scheduler trata cada método decorado como un job independiente con su propio nombre y ciclo de vida.

src/modules/tasks/services/maintenance.service.ts
import { Injectable } from '@spraxium/common';
import {
  Cron,
  CronExpression,
  Interval,
  IntervalExpression,
  AfterOnline,
} from '@spraxium/schedule';

@Injectable()
export class MaintenanceService {
  @Cron(CronExpression.EVERY_DAY_AT_3AM, { name: 'daily-cleanup' })
  async dailyCleanup(): Promise<void> {
    // Archive old logs, clear temp data
  }

  @Interval(IntervalExpression.EVERY_10_MINUTES, { name: 'health-ping' })
  async healthPing(): Promise<void> {
    // Report bot health to monitoring service
  }

  @AfterOnline(10_000, { name: 'restore-presences' })
  async restorePresences(): Promise<void> {
    // Restore bot status from database after reconnection
  }
}

Ejecución condicional de jobs con feature flags

A veces quieres definir un job pero habilitarlo solo según variables de entorno o condiciones de runtime. La opción disabled en las opciones del decorador te permite controlarlo en el momento de registro. Para control en runtime, usa en su lugar los métodos ScheduleService.pause y ScheduleService.resume.

src/modules/tasks/services/analytics.service.ts
import { Injectable } from '@spraxium/common';
import { Cron, CronExpression } from '@spraxium/schedule';

@Injectable()
export class AnalyticsService {
  @Cron(CronExpression.EVERY_HOUR, {
    name: 'hourly-analytics',
    disabled: process.env.ENABLE_ANALYTICS !== 'true',
  })
  async collectAnalytics(): Promise<void> {
    // Collect and aggregate usage analytics
  }
}

Registro del módulo

Registra tus servicios de tasks como providers dentro de un módulo. ScheduleModule es global y no necesita importarse en tu módulo de funcionalidad. Solo añade tus servicios al arreglo de providers y el scheduler descubrirá automáticamente sus métodos decorados.

src/modules/tasks/tasks.module.ts
import { Module } from '@spraxium/common';
import { CleanupService } from './services/cleanup.service';
import { SyncService } from './services/sync.service';
import { MaintenanceService } from './services/maintenance.service';

@Module({
  providers: [CleanupService, SyncService, MaintenanceService],
})
export class TasksModule {}