Skip to content

Commit

Permalink
support time zone and distributed
Browse files Browse the repository at this point in the history
  • Loading branch information
miaowing committed Aug 23, 2018
1 parent c4d6202 commit 07e543a
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 67 deletions.
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,35 @@ $ npm i --save nest-schedule

```typescript
import { Injectable } from '@nestjs/common';
import { Schedule, NestSchedule } from 'nest-schedule';
import { Cron, Interval, Timeout, NestSchedule } from 'nest-schedule';

@Injectable()
export class ScheduleService extends NestSchedule {
constructor() {
super();
}

@Schedule({
cron: '0 0 2 * *',
@Cron('0 0 2 * *', {
startTime: new Date(),
endTime: new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
endTime: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
tz: 'Asia/Shanghai',
})
async syncData() {
console.log('syncing data ...');
}

@Schedule({cron: '0 0 4 * *'})
@Cron('0 0 4 * *')
async clear() {
console.log('clear data ...');
await doClear();
}

@Schedule({timeout: 5000})
@Timeout(5000)
onceJob() {
console.log('once job');
}

@Schedule({interval: 2000})
@Interval(2000)
intervalJob() {
console.log('interval job');

Expand All @@ -77,6 +77,34 @@ export class ScheduleService extends NestSchedule {
}
```

### Distributed Support

```typescript
import { Injectable } from '@nestjs/common';
import { Cron, NestDistributedSchedule } from 'nest-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 ...');
}
}
```

## Stay in touch

- Author - [Miaowing](https://github.com/miaowing)
Expand Down
73 changes: 73 additions & 0 deletions lib/NestDistributedSchedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as schedule from "node-schedule";
import { NEST_SCHEDULE_JOB_KEY } from "./constants";

export abstract class NestDistributedSchedule {
private readonly jobs;
private readonly timers = {};

protected constructor() {
this.jobs = Reflect.getMetadata(NEST_SCHEDULE_JOB_KEY, new.target.prototype);
this.init();
}

abstract async tryLock(method: string): Promise<() => void>;

private async do(invoked) {
if (invoked instanceof Promise) {
return await invoked;
}
return invoked;
}

private init() {
if (this.jobs) {
this.jobs.forEach(async job => {
if (job.cron) {
job = schedule.scheduleJob({
startTime: job.startTime,
endTime: job.endTime,
rule: job.cron
}, async () => {
try {
const release = await this.do(this.tryLock(job.key));
const result = await this.do(this[job.key]());
if (result && job) {
job.cancel();
}
typeof release === "function" ? release() : void 0;
} catch (e) {
}
});
}
if (job.interval) {
this.timers[job.key] = setInterval(async () => {
try {
const release = await this.do(this.tryLock(job.key));
const result = await this.do(this[job.key]());
if (result && this.timers[job.key]) {
clearInterval(this.timers[job.key]);
delete this.timers[job.key];
}
typeof release === "function" ? release() : void 0;
} catch (e) {
}
}, job.interval);
}
if (job.timeout) {
this.timers[job.key] = setTimeout(async () => {
try {
const release = await this.do(this.tryLock(job.key));
const result = await this.do(this[job.key]());
if (result && this.timers[job.key]) {
clearTimeout(this.timers[job.key]);
delete this.timers[job.key];
}
typeof release === "function" ? release() : void 0;
} catch (e) {
}
}, job.timeout);
}
});
}
}
}
60 changes: 4 additions & 56 deletions lib/NestSchedule.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,7 @@
import "reflect-metadata";
import { NEST_SCHEDULE_JOB_KEY } from "./constants";
import * as schedule from "node-schedule";
import { NestDistributedSchedule } from "./NestDistributedSchedule";

export class NestSchedule {
private readonly jobs;
private readonly timers = {};

constructor() {
this.jobs = Reflect.getMetadata(NEST_SCHEDULE_JOB_KEY, new.target.prototype);
this.init();
}

private init() {
if (this.jobs) {
this.jobs.forEach(job => {
if (job.cron) {
job = schedule.scheduleJob({
startTime: job.startTime,
endTime: job.endTime,
rule: job.cron
}, async () => {
let result = this[job.key]();
if (result instanceof Promise) {
result = await result;
}
if (result && job) {
job.cancel();
}
});
}
if (job.interval) {
this.timers[job.key] = setInterval(async () => {
let result = this[job.key]();
if (result instanceof Promise) {
result = await result;
}
if (result && this.timers[job.key]) {
clearInterval(this.timers[job.key]);
delete this.timers[job.key];
}
}, job.interval);
}
if (job.timeout) {
this.timers[job.key] = setTimeout(async () => {
let result = this[job.key]();
if (result instanceof Promise) {
result = await result;
}
if (result && this.timers[job.key]) {
clearTimeout(this.timers[job.key]);
delete this.timers[job.key];
}
}, job.timeout);
}
});
}
export class NestSchedule extends NestDistributedSchedule {
async tryLock(method: string): Promise<any> {
return false;
}
}
12 changes: 11 additions & 1 deletion lib/Schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@ export interface Options {
timeout?: number;
startTime?: Date;
endTime?: Date;
tz?: string;
}

export const Schedule = (options: Options) => (target, key, descriptor) => {
export const Schedule = (options: Options) => createSchedule(options);
export const Interval = (milliseconds: number) => createSchedule({ interval: milliseconds });
export const Timeout = (milliseconds: number) => createSchedule({ timeout: milliseconds });
export const Cron = (cron: string, options: {
startTime?: Date,
endTime?: Date,
tz?: string
} = {}) => createSchedule({ cron, ...options });

const createSchedule = (options: Options) => (target, key, descriptor) => {
let jobs = Reflect.getMetadata(NEST_SCHEDULE_JOB_KEY, target);
if (!jobs) {
jobs = [];
Expand Down
3 changes: 2 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./Schedule";
export * from "./NestSchedule";
export * from "./constants";
export * from "./constants";
export * from "./NestDistributedSchedule";
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nest-schedule",
"version": "0.2.1",
"version": "0.3.0",
"description": "Nest - modern, fast, powerful node.js web framework (@schedule)",
"author": "Miaowing <[email protected]>",
"license": "MIT",
Expand Down

0 comments on commit 07e543a

Please sign in to comment.