Node

Cron jobs, timeouts e intervals com NestJS

Neste artigo vamos utilizar o módulo nativo scheduler do NestJS para trabalhar com tarefas automatizadas com cron jobs, timeouts e intervals

há 5 meses 2 semanas

Formação Desenvolvedor Node Full-Stack
Conheça a formação em detalhes

Neste artigo vamos aprender a automatizar tarefas utilizando cron jobs, timeouts e intervals com o NestJS.

O que é cron job?

Nos sisetmas Unix temos a possibilidade de programar tarefas automatizadas, esse recurso se chama “cron jobs”. Podemos automatizar programas, scripts, comandos e etc.

O interessante é que além da frequência de “tempo”, é possível escolher esta frequência de forma mais precisa, como em horários e determinados dias da semana, entre outras possibilidades.

Para isto é necessário utilizar um arquivo de configuração chamado “crontab”, que segue a seguinte sintaxe:

* * * * * comando_a_executar

Cada asterisco representa o tempo a ser configarado relacionado a frequência da execução da tarefa, como a tabela abaixo:

* * * * *
| | | | |
| | | | dia da semana
| | | meses
| | dia do mês
| horas
minutos

Portanto, podemos simular esse recurso em nossas aplicações, automatizando a execução de métodos e trazendo flexibilidade para implementar tarefas cada vez mais robustas e eficazes.

Você pode simular essas configurações de agendamento de tarefas utilizando o site contrab.guru.

Implementando exemplo

Primeiro de tudo, você deve ter o Node.js instalado, conforme pode seguir o passos pelo artigo instalando node.js no Windows, Mac e Linux.

Node.js - Fundamentos
Curso Node.js - Fundamentos
Conhecer o curso

Logo em seguida vamos criar um projeto base com o NestJS, mas antes precisamos instalar o NestCLI com o seguinte comando:

npm i -g  @nestjs/cli

Configurando projeto base

Agora vamos criar um projeto para demonstrar alguns exemplos:

nest new tasks

Também é necessário instalar o pacote schedule do NestJS:

npm i @nestjs/schedule

Criando exemplo

Vamos pensar como podemos utilizar na prática a utilização dessas tarefas automatizadas.

Em um determinado contexto temos uma tabela pedidos, onde os pedidos devem ser pagos em até, no máximo, 24 horas. Se este tempo for ultrapassado, os pedidos são cancelados automaticamente. Portanto, podemos criar uma tarefa que a cada minuto busca os pedidos que estão em aberto por mais de 24 horas e altera seu status para cancelado.

Para isto vamos criar uma pasta schedule, e dentro desta pasta um arquivo schedule.service.ts:

//schedule.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class ScheduleService {}

Perfeito, devemos atualizar o arquivo app.module.ts que se encontra na pasta src, importando o modulo instalado acima e adicionando o schedule.service.ts na propriedade providers:

//app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ScheduleServiceService } from './schedule/schedule-service.service';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [ScheduleModule.forRoot()],
  controllers: [AppController],
  providers: [AppService, ScheduleService],
})
export class AppModule {}

Vamos implementar um método que irá simular a ação de alterar o status dos pedidos em um determinado tempo:

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class ScheduleService {
  private readonly logger = new Logger(ScheduleService.name);

  @Cron('*/5 * * * * *')
  cancelarPedidoSemPagamento() {
    //lógica para buscar e cancelar os pedidos.
    this.logger.debug(
      `Pedido de n: ${Math.floor(Math.random() * 120)} cancelado!`,
    );
  }
}

Ao executar o código acima, o método cancelarPedidoSemPagamento() foi executado a cada 5 segundos automaticamente:

Aplicação executando método a cada 5 segundos com cron job

Para isto utilizamos o decorator @Cron() e passamos como parâmetro a frequência que o método será executado, podendo ter infinitas combinações:

* * * * * *
| | | | | |
| | | | | dia da semana
| | | | meses
| | | dia do mês
| | horas
| minutos
segundos (opcional)

Alguns exemplos que constam na própria documentação do NestJS:

* * * * * * a cada segundo
45 * * * * * a cada minuto, no 45º segundo
0 10 * * * * a cada hora, no início do 10º minuto
0 */30 9-17 * * * a cada 30 minutos entre as 9h e as 17h
0 30 11 * * 1-5 de segunda a sexta-feira às 11h30min

Nest.js - Fundamentos
Curso Nest.js - Fundamentos
Conhecer o curso

Usando enums

O interessante é que o NestJS, além da facilidade do uso de decorators para trabalhar com cron jobs, também permite que seja utilizado enums como parâmetro, deixando o código mais legivel e fácil de desenvolver:

utilizando enums como parâmetro do decorator cron

Temos outras possibilidade também de trabalhar com o tempo em relação a execução dos métodos, por exemplo utilizando o decorator Interval() e o Timeout().

Utilizando Interval()

Com o decorator Interval() podemos passar como parâmetro o tempo, em milissegundos, sobre o intervalo de execução do método, por exemplo:

import { Injectable, Logger } from '@nestjs/common';
import { Interval } from '@nestjs/schedule';

@Injectable()
export class ScheduleService {
  private readonly logger = new Logger(ScheduleService.name);

  @Interval(5000)
  cancelarPedidoSemPagamento() {
    //lógica para buscar e cancelar os pedidos.
    this.logger.debug(
      `Pedido de n: ${Math.floor(Math.random() * 120)} cancelado!`,
    );
  }
}

Aplicação executando método com interval Neste exemplo o método foi executado a cada 5 segundos, conforme definido no decorator Interval()

Utilizando Timeout()

Podemos também definir uma única execução após um determinado tempo, para isso usamos o decorator Timeout(), também passando o tempo em milissegundos como parâmetro.

import { Injectable, Logger } from '@nestjs/common';
import { Timeout } from '@nestjs/schedule';

@Injectable()
export class ScheduleService {
  private readonly logger = new Logger(ScheduleService.name);

  @Timeout(5000)
  cancelarPedidoSemPagamento() {
    //lógica para buscar e cancelar os pedidos.
    this.logger.debug(
      `Pedido de n: ${Math.floor(Math.random() * 120)} cancelado!`,
    );
  }
}

Aplicação executando método timeout Neste exemplo o método foi executado somente uma vez, após 5 segundos, conforme definido no decorator Timeout()

Nest.js  - Banco de dados com TypeORM
Curso Nest.js - Banco de dados com TypeORM
Conhecer o curso

Conclusão

Neste artigo abordamos a base do uso de cron jobs, timeouts e intervals, lembrando que o próprio NestJS provê o pacote schedule, que facilita a utilização desses recursos através de decorators. Podemos também nos aprofundar na utilização desses recursos através da Dynamic API, que fornece possibilidade de trabalhar com instancias de destes recursos em qualquer lugar da aplicação e gerenciá-los, onde veremos como nos próximos artigos em um futuro breve.

Por fim, caso queira aprender mais sobre NestJS saiba que aqui na TreinaWeb temos o curso Nest.js - Fundamentos que possui 02h07 de vídeos e um total de 18 exercícios. Conheça também nossos outros cursos de TypeScript.

Veja quais são os tópicos abordados durante o curso de Nest.js - Fundamentos:

  • Conhecendo a estrutura;
  • Utilizando Nest CLI;
  • Entendendo Rotas, Controllers e Views;
  • Conexão com banco de dados;
  • Usando TypeORM;
  • Template Engine.

Autor(a) do artigo

Wesley Gado
Wesley Gado

Formado em Análise e Desenvolvimento de Sistemas pelo Instituto Federal de São Paulo, atuou em projetos como desenvolvedor Front-End. Nas horas vagas grava Podcast e arrisca uns três acordes no violão.

Todos os artigos

Artigos relacionados Ver todos