Spraxium logoSpraxium

Configuração e padrões

A config de schedule usa o padrão de configuração separada com defineSchedule para um setup com segurança de tipos. Conheça a referência completa de ScheduleConfig, as boas práticas e os padrões de job mais comuns.

Padrão de configuração separada

Assim como outros plugins do Spraxium, o módulo de schedule usa o padrão de configuração separada, em que a configuração vive em um arquivo dedicado dentro do diretório config/. O helper defineSchedule fornece segurança de tipos completa e auto-complete para todos os campos de configuração. O seu spraxium.config.ts principal referencia esse arquivo, mantendo a config raiz limpa e cada configuração de plugin isolada.

Cada plugin tem o próprio arquivo de configuração com suas próprias definições de tipo, e a config raiz apenas importa e compõe esses arquivos. Assim, você evita terminar com um objeto de configuração monolítico misturando ajustes de prefix, schedule e HTTP.

O framework descobre e carrega automaticamente a config de schedule durante o bootstrap. Você não precisa chamar nenhuma função de registro manualmente. Basta exportar a config do arquivo e referenciá-la no array de imports da sua config raiz.

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

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

Referência de ScheduleConfig

A interface ScheduleConfig controla o comportamento global de todos os jobs agendados. A maioria dos campos é opcional e tem defaults sensatos que funcionam bem em bots de processo único.

CampoTipoPadrãoDescrição
driverScheduleDriverMemoryDriverDriver de lock para execução distribuída
timezonestringDefault do sistemaFuso horário IANA para jobs cron
defaultLockTtlMsnumber30000TTL padrão do lock em milissegundos para o driver
disableAllbooleanfalseDesabilita todos os jobs globalmente, útil para manutenção

Organização do projeto

Serviços de schedule são providers injetáveis comuns que você registra em qualquer módulo. Um padrão frequente é criar um módulo dedicado de tasks para agrupar todos os jobs em segundo plano, mas você também pode colocar métodos decorados com schedule em serviços específicos de domínio. A escolha depende de os seus jobs serem transversais, como limpeza e sincronização, ou fortemente acoplados a uma funcionalidade específica.

Para tarefas transversais, um módulo centralizado de tasks ajuda a manter tudo organizado. Para tarefas específicas de uma funcionalidade, colocar o decorator de schedule em um método do serviço da feature evita indireção desnecessária. As duas abordagens são válidas, e o framework trata ambas da mesma forma.

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

Padrões comuns

Combinando vários tipos de job em um serviço

Um único serviço pode ter métodos decorados com tipos de job diferentes. Isso é útil quando tarefas relacionadas têm exigências de tempo distintas, mas compartilham as mesmas dependências. O scheduler trata cada método decorado como um job independente, com nome e ciclo de vida próprios.

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
  }
}

Execução condicional de jobs com feature flags

Em alguns casos, você quer definir um job, mas só habilitá-lo com base em variáveis de ambiente ou condições de runtime. A opção disabled nas opções do decorator permite controlar isso no momento do registro. Para controle em runtime, use os métodos ScheduleService.pause e 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 do módulo

Registre seus serviços de task como providers em um módulo. O ScheduleModule é global e não precisa ser importado no seu feature module. Basta adicionar os serviços ao array de providers, e o scheduler descobrirá automaticamente os 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 {}