npm package: @proscom/nestjs-schedule
Description: Scheduling module for nestjs
Author: Proscom
Latest version: 0.6.1

<p align="center">
  <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>

# nestjs-schedule

## Description

This is a [Nest](https://github.com/nestjs/nest) module for using decorator schedule a job.
It uses `node-schedule` as the base for the cron-like task execution.

This project is a fork of [miaowing/nest-schedule](https://github.com/miaowing/nest-schedule) 
aimed to deliver better functionality.

## Installation

```bash
$ npm i --save @proscom/nestjs-schedule
```
or

```bash
$ yarn add @proscom/nestjs-schedule
```

## Quick Start

You can declare commands to be executed by creating a service extending the base `NestSchedule` class.

```typescript
import { Injectable, LoggerService } from '@nestjs/common';
import { Cron, Interval, Timeout, NestSchedule, defaults } from '@proscom/nestjs-schedule';

defaults.enable = true;
defaults.logger = new NestLogger();
defaults.maxRetry = -1;
defaults.retryInterval = 5000;

export class NestLogger implements LoggerService {
    log(message: string): any {
        console.log(message);
    }

    error(message: string, trace: string): any {
        console.error(message, trace);
    }

    warn(message: string): any {
        console.warn(message);
    }
}

@Injectable()
export class ScheduleService extends NestSchedule {  
  constructor(
    
  ) {
    super();
  }
  
  @Cron('0 0 2 * *', {
    startTime: new Date(), 
    endTime: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
    tz: 'Asia/Shanghai',
  })
  async syncData() {
    console.log('syncing data ...');
  }
  
  @Cron('0 0 4 * *')
  async clear() {
    console.log('clear data ...');
    await doClear();
  }
  
  @Timeout(5000)
  onceJob() {
    console.log('once job');
  }
  
  @Interval(2000)
  intervalJob() {
    console.log('interval job');
    
    // if you want to cancel the job, you should return true;
    return true;
  }
}
```

To start the scheduler you should call the `init` function of the created service.
You can do this in a bootstrap function of your nestjs `main.ts` file:

```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  app
    .select(AppModule)
    .get(ScheduleService)
    .init();
  
  await app.listen(3000);
}

bootstrap()
  .catch((e) => console.error(`Uncatched error`, e));
```

You can also call `init` from a different file in order to start scheduler as a separate process.
It can be useful in distributed deploys using docker.

### Distributed Support

```typescript
import { Injectable } from '@nestjs/common';
import { Cron, NestDistributedSchedule } from '@proscom/nestjs-schedule';

@Injectable()
export class ScheduleService extends NestDistributedSchedule {  
  constructor() {
    super();
  }
  
  async tryLock(method: string) {
    // If try lock fail, you should throw an error.
    throw new Error('try lock fail');
    
    return () => {
      // Release here.
    }
  }
  
  @Cron('0 0 4 * *')
  async clear() {
    console.log('clear data ...');
  }
}
```

## API

### Common options or defaults

| field | type | required | description |
| --- | --- | --- | --- |
| enable | boolean | false | default is true, when false, the job will not execute |
| maxRetry | number | false |  the max retry count, default is -1 not retry |
| retryInterval | number | false | the retry interval, default is 5000 |
| logger | LoggerService | false | default is false, only available at defaults |

### Cron(expression: string, options: CronOptions)

| field | type | required | description |
| --- | --- | --- | --- |
| expression | string | true | the cron expression |
| options.startTime | Date | false | the job's start time |
| options.endTime | Date | false | the job's end time |
| options.tz | string | false | the time zone |

### Interval(time: number, options: BaseOptions)

| field | type | required | description |
| --- | --- | --- | --- |
| time | number | true | millisecond |
| options | object | false | same as common options |

### Timeout(time: number, options: BaseOptions)

| field | type | required | description |
| --- | --- | --- | --- |
| time | number | true | millisecond |
| options | object | false | same as common options |

## License

  This package is [MIT licensed](LICENSE).