LoginSignup
14
10

More than 5 years have passed since last update.

Sails.js に定時にバッチ処理を行わせる

Last updated at Posted at 2014-12-14

Sails の便利な機能や自分が作った Model を使ってバッチ処理を定期的にやりたいとかありますよね。

同じことを考えた人たちが既に何人かいて、Issue に投稿してたりしてるんですが、本家に採り入れられるまでには至ってません。
(「誰か Pull Request 送ってくれれば採用するよ」と言ってますが、今のところ誰もやってない。残念)

色々書き方はあるようですが、できるだけ Sails の素直なスタイルで最小限に書ける方法をここでは紹介します。

必要な NPM パッケージをインストール

定時実行と言えば UNIX システムの cron が思い浮かびますが、OS の機能に依存するのはイケてません。Node のサーバは常に起動されているはずなので、Node に実行してもらいましょう。

node-cron という NPM パッケージを使います。タイムゾーン指定に node-time も必要なので、併せてインストールします。

$ npm install cron --save
$ npm install time --save

config/crontab.js を作成

config/ ディレクトリに crontab.js というファイルを作成して、そこにタイムテーブルと実行したい処理を JSON 形式で記述します。

config/crontab.js
module.exports.crontab = {

  "*/10 * * * *": function hoge() {
    // 10分ごとに /tmp/hoge-{NOW}.txt ファイルを作成する
    var fs = require('fs');
    var file = '/tmp/hoge-' + Date.now() + '.txt';

    fs.writeFile(file, Date.now(), function(err) {
      if (err) {
        sails.log.error("Hoge file writing error occured.");
        throw err;
      } else {
        sails.log("Hoge file has been wrote successfully.");
      }
    });
  },

  "0,15,30,45 * * * *": function piyo() {
    // 15分ごとに /tmp/piyo-{NOW}.txt ファイルを作成する
    var fs = require('fs');
    var file = '/tmp/piyo-' + Date.now() + '.txt';

    fs.writeFile(file, Date.now(), function(err) {
      if (err) {
        sails.log.error("Piyo file writing error occured.");
        throw err;
      } else {
        sails.log("Piyo file has been wrote successfully.");
      }
    });
  }
}

タイムテーブルの書式は UNIX システムの cron と同じで以下の通り。

曜日
0-59 0-23 1-31 1-12 0-7

詳しくは crontab の man 等を参照のこと。

config/bootstrap.js で登録

config/bootstrap.js は Sails 起動時に実行したい処理を書いておくためのファイルですが、ここで crontab.js に記述されたジョブを登録するようにします。

config/bootstrap.js
module.exports.bootstrap = function(cb) {

  cb();

  // Register cron jobs
  var CronJob = require('cron').CronJob;
  var jobs = sails.config.crontab;

  for (table in jobs) {
    if (typeof table === 'string') {
      new CronJob(table, jobs[table], null, true, 'Asia/Tokyo');
    }
  }

これで、sails lift すると、config/crontab.js に記述された処理が定時実行されます。

なお注意点として、タイムテーブルの文字列を JSON のキーにしているため、同じタイムテーブルの処理を config/crontab.js に並べて記述すると、先に書いたものが上書きされてしまいます。同じタイムテーブルで実行したい処理がある場合は、まとめて書いておきましょう。

crontab.jsのダメな例
module.exports.crontab = {
  "0 9 * * *": function hoge() { /** hogeの処理 **/ }, // 上書きされる
  "0 9 * * *": function piyo() { /** piyoの処理 **/ }
}

もうちょっと整理して書くには

上の例では crontab.js に処理を直書きしてますが、もうちょっと整理して書きたい場合は、処理そのものは api/services/ に書いて、crontab.js ではそれをコールするだけというようにすると、すっきりした構造になります。

14
10
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
14
10