2
1

More than 1 year has passed since last update.

Node Scheduleで定期処理を行う

Posted at

プロジェクトでnode-scheduleライブラリを使って定期処理を行いました。
この記事は自分用メモです。

Node Scheduleの概要

Node Scheduleはインターバルベースではなく(interval-base),タイムベース(time-base)で定期処理を行います。

例えば、2021年11月8日にあるプロセス(メソッド)を実行したい場合、適切なパッケージだと思います。

Node Scheduleはcron-style schedulingです。

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    │
│    │    │    │    │    └ day of week (0 - 7) (0 or 7 is Sun)
│    │    │    │    └───── month (1 - 12)
│    │    │    └────────── day of month (1 - 31)
│    │    └─────────────── hour (0 - 23)
│    └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, OPTIONAL)

Node Scheduleの書式

Node Scheduleの詳しいドキュメントを読みたい場合、以下に2つのURLが貼られています。

node-schedule パッケージのインストール

最初に、node-scheduleパッケージをインストールします。

$ npm i node-schedule

node-scheduleパッケージの試し

1. Cron format

cron フォマットの例を述べます。秒数が30になる時、ジョブ(job)は実行されます。
(cronはNode.jsで定期実行メモを参照します)

/// test.js
const schedule = require('node-schedule');

const job = schedule.scheduleJob('30 * * * * *', function(){
    var date = new Date();
    console.log('hh:mm:30に実行します'+date);
  });

出力は以下のようになります。

$ node test.js 
hh:mm:30に実行しますMon Nov 08 2021 16:12:30 GMT+0900 (Japan Standard Time)
hh:mm:30に実行しますMon Nov 08 2021 16:13:30 GMT+0900 (Japan Standard Time)
hh:mm:30に実行しますMon Nov 08 2021 16:14:30 GMT+0900 (Japan Standard Time)
hh:mm:30に実行しますMon Nov 08 2021 16:15:30 GMT+0900 (Japan Standard Time)

メソッドを外に宣言する場合は以下のようになります。出力は同じです。

/// test.js
const schedule = require('node-schedule');

var process = function() {
    var date = new Date();
    console.log('hh:mm:30に実行します'+date);
}

const job = schedule.scheduleJob('30 * * * * *', process);

2. デートベース・スケジューリング

決められた時間にジョブを実行したい時、デートベーススケジューリング(Date-based scheduling)を使います。

/// test.js
const schedule = require('node-schedule');

var process = function() {
    var date = new Date()
    console.log("実行されています。" + date)
}

var scheduleTime = new Date("November 08, 2021 16:35:00")

const job = schedule.scheduleJob(scheduleTime, process);

出力は以下のようになります。ジョブが終わったら、プログラムも終了します。

$ node test.js 
実行されています。Mon Nov 08 2021 16:35:00 GMT+0900 (Japan Standard Time)
$ 

3. 複数のジョブ

プロジェクトでは複数のジョブをスケジュールしました。以下のようなdummy例を述べます。スケジュールリストを作成し、各要素は実行時間とコンテンツを持っています。

ここはscheduleJobsで登録したジョブを確認できます。

/// test.js
const schedule = require('node-schedule');

var process = function(job) {
    var time = job['processTime'];
    var content = job['processContent'];

    var date = new Date()
    var curr = new Date()
    date.setTime(time)
    console.log(curr);
    console.log(content + " 実行されています。" + date)
}

var time1 = new Date("November 08, 2021 18:07:00").getTime()
var time2 = new Date("November 08, 2021 18:09:00").getTime()

const scheduleList = [
    {
        processTime: time1,
        processContent: "プロセス1",

    },
    {
        processTime: time2,
        processContent: "プロセス2",
    }
]

// ジョブの登録
for (var i = 0; i < scheduleList.length; i++) {
    var job =  scheduleList[i];
    var processTime = job['processTime'];
    var processContent = job['processContent'];

    //scheduleJobのパラメーター: ジョブ名, 実行時間, 実行メソッド
    schedule.scheduleJob(processContent, new Date().setTime(processTime),function(job){
        process(job);
        console.log("現時点のスケジュール")
        console.log(schedule.scheduledJobs)
    }.bind(null,job))
}

// 登録したジョブを確認する
console.log("登録したジョブを確認する")
console.log(schedule.scheduledJobs)


このコードの出力はこのようになります。

$ node test.js 
登録したジョブを確認する
{
  'プロセス1': Job {
    pendingInvocations: [ [Invocation] ],
    job: [Function: bound ],
    callback: false,
    name: 'プロセス1',
    trackInvocation: [Function (anonymous)],
    stopTrackingInvocation: [Function (anonymous)],
    triggeredJobs: [Function (anonymous)],
    setTriggeredJobs: [Function (anonymous)],
    deleteFromSchedule: [Function (anonymous)],
    cancel: [Function (anonymous)],
    cancelNext: [Function (anonymous)],
    reschedule: [Function (anonymous)],
    nextInvocation: [Function (anonymous)],
    isOneTimeJob: true
  },
  'プロセス2': Job {
    pendingInvocations: [ [Invocation] ],
    job: [Function: bound ],
    callback: false,
    name: 'プロセス2',
    trackInvocation: [Function (anonymous)],
    stopTrackingInvocation: [Function (anonymous)],
    triggeredJobs: [Function (anonymous)],
    setTriggeredJobs: [Function (anonymous)],
    deleteFromSchedule: [Function (anonymous)],
    cancel: [Function (anonymous)],
    cancelNext: [Function (anonymous)],
    reschedule: [Function (anonymous)],
    nextInvocation: [Function (anonymous)],
    isOneTimeJob: true
  }
}
2021-11-08T09:07:00.005Z
プロセス1 実行されています。Mon Nov 08 2021 18:07:00 GMT+0900 (Japan Standard Time)
現時点のスケジュール
{
  'プロセス1': Job {
    pendingInvocations: [],
    job: [Function: bound ],
    callback: false,
    name: 'プロセス1',
    trackInvocation: [Function (anonymous)],
    stopTrackingInvocation: [Function (anonymous)],
    triggeredJobs: [Function (anonymous)],
    setTriggeredJobs: [Function (anonymous)],
    deleteFromSchedule: [Function (anonymous)],
    cancel: [Function (anonymous)],
    cancelNext: [Function (anonymous)],
    reschedule: [Function (anonymous)],
    nextInvocation: [Function (anonymous)],
    isOneTimeJob: true
  },
  'プロセス2': Job {
    pendingInvocations: [ [Invocation] ],
    job: [Function: bound ],
    callback: false,
    name: 'プロセス2',
    trackInvocation: [Function (anonymous)],
    stopTrackingInvocation: [Function (anonymous)],
    triggeredJobs: [Function (anonymous)],
    setTriggeredJobs: [Function (anonymous)],
    deleteFromSchedule: [Function (anonymous)],
    cancel: [Function (anonymous)],
    cancelNext: [Function (anonymous)],
    reschedule: [Function (anonymous)],
    nextInvocation: [Function (anonymous)],
    isOneTimeJob: true
  }
}
2021-11-08T09:09:00.004Z
プロセス2 実行されています。Mon Nov 08 2021 18:09:00 GMT+0900 (Japan Standard Time)
現時点のスケジュール
{
  'プロセス2': Job {
    pendingInvocations: [],
    job: [Function: bound ],
    callback: false,
    name: 'プロセス2',
    trackInvocation: [Function (anonymous)],
    stopTrackingInvocation: [Function (anonymous)],
    triggeredJobs: [Function (anonymous)],
    setTriggeredJobs: [Function (anonymous)],
    deleteFromSchedule: [Function (anonymous)],
    cancel: [Function (anonymous)],
    cancelNext: [Function (anonymous)],
    reschedule: [Function (anonymous)],
    nextInvocation: [Function (anonymous)],
    isOneTimeJob: true
  }
}

以上の結果によると、プロセス2を実行する時、スケジュールにプロセス1が排除されることがわかります。

cronではないフォマットをスケジュールしたい場合はNode Scheduleが良いと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1