用于在node.js中处理具有延迟的队列中的请求的后台服务

时间:2017-07-31 11:22:29

标签: javascript node.js

我甚至不确定应该如何询问,但这是我的情景:

我有一个不时更新或刷新的记录列表。对于其中一些记录,我想调用API来获取一些日期。问题是API有一些限制,例如,每小时只有100次调用。

我需要一种机制来:

  • 在后台运行并检查是否有新记录需要处理

  • 如果有新记录将它们分成100块,然后每1小时用100条记录调用API

  • 下次检查时,如果有新记录,请附加等等

在node.js中实现此目的的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

先决条件

将记录保存在记忆中,特别是当存在未知数量的记录时,这是不好的做法。为了使这个伪示例起作用,您需要这些记录的集合/表及其所有当前值+它需要有一个字段.isChecked=false。这样,数据库查询将返回前100个未经检查的记录,我们不需要在应用程序级别对其进行管理。

首先,我们需要一个调度程序,以便每1小时完全触发一次任务。为此,我们将使用cron-jobs npm install cron docs here

创建3个文件:API.js,checker.js,cron.js

cron.js - 调度程序文件(最佳触发后应用程序启动)

let CronJob = require('cron').CronJob;
let DB = require('some-DB');

let APIChecker = require('./checker.js');
let APICheckerInstance = APIChecker({url: "http://my-api.com"});

var job = new CronJob('00 00 * * * *', function() {
    //exeute script for every hour ( 00 secod mark, 0 minute mark, every hour)
    let records = DB.get("records which have isChecked=false").toArray(); //pseudo code
    APIChecker.check(records, function (err, result=null) {
        // handle callback/ can return results or error
        // DB.massUpdate(result)
    })
}, function () {
    console.log("Job has finished");
});

chcker.js - 检查/修改数据的逻辑

'use strict';

const
    util = require('util'),
    API = require('./api.js');

module.exports = function (options) {

    function MyAPIChecker (options) {
        this.result = [];
        API.call(this, options);
    }

    util.inherits(MyAPIChecker, API);

    MyAPIChecker.prototype.check = function (records, callback) {
        this.result = [];
        let temp = records.length;

        for(let i = 0; i < records.length; i++) {
            this.makeRequest(records[i])
                .then(result => {
                    records[i].isChecked = true;
                    // add stuff from result
                    // or return stuff with callback for processing
                    if (!--temp) return callback(null, records)
                })
        }
    }
    return new MyAPIChecker(options);
}

api.js - 为HTTP请求保留的API

'use strict';

const
    request = require('your-request-lib');

module.exports = (function () {

    function API (options) {
        this.options = options;
    }

    API.prototype.prepareRequest = function (record) {
        // prepare http(s) options;
        // get URL and such from this.options ( pass it to the constructor )
        // use record data
        return options
    }

    API.prototype.makeRequest = function (record) {
        let opts = this.prepareRequest(record);
        // or any other verb
        return request.get(opts);
    }

    return API;
})()

希望您会发现此示例很有用。