【问题标题】:Poll REST API for long running task轮询 REST API 以获取长时间运行的任务
【发布时间】:2017-06-22 23:22:37
【问题描述】:

我正在设计一个 REST API 来执行一些需要大量计算的任务,以供其他服务使用。本质上,对/command 的GET 请求将开始任务,状态将在/queue/12345 处更新。客户端轮询/queue/12345/,直到任务完成,此时服务器发送一个带有结果位置的303(/runs/12345)。

我现在要做的是在客户端编写轮询函数。我现在拥有的可以成功轮询 - 但是,因为setTimeout() 函数在请求发送后立即被调用。这意味着我将永远轮询,即使我没有在请求的回调函数中调用setTimeout()

如何确保收到 303 状态码后我的投票功能结束?

// standard first call is pollQueue(uri, 0);
function pollQueue(uri, timesPolled, callback) {
    if(timesPolled > 28800) {
        // 288800 is (60 sec/min * 60 min/hr * 24 hr) / 3 sec/poll. Aka 24 hours.
        throw 'ResourceWillNeverBeReady';
    }

    console.log("polling " + uri);
    request({
      url: "http://localhost:2500/" + uri,
      followRedirect: false
    }, function (error, response, body) {
        if(response.statusCode === 303) {
            // callback handles requesting the actual data
            callback(response.headers.location); 
            return;
        }
    });

    setTimeout(function() { pollQueue(uri, timesPolled + 1, callback);}, 3000);
}

【问题讨论】:

  • 我的意思是,是的,这就是您的代码的作用。它发送请求,然后不等待它完成它启动计时器以发送下一个。
  • 哦。是的。我知道这就是问题所在,但没有将我需要将 setTimeout() 函数放入回调中的事实联系起来。
  • 另外,这看起来不像长轮询,通常使用长轮询您发送一个请求,然后服务器会保留它一段时间(10-30 秒,也许更多)和只有当值发生变化时才会提前响应,因此与在服务器上发生更新相比,UI 上的更新之间的延迟非常小。
  • 是的,不是。在我的实际应用程序中,任务可能需要 1 分钟到 ~2-3 小时,具体取决于命令。所以我想为每次民意调查等待大约 30 秒,而不是我现在的 3 秒。您认为在这种情况下,长轮询仍然会更好吗?
  • 嗯,这取决于。用户是否希望此窗口保持打开 2-3 小时?电子邮件通知可能更适合可能需要很长时间的事情。

标签: javascript node.js rest


【解决方案1】:

Kevin B 指出了显而易见的事实。我需要做的就是将setTimeout() 函数移到回调中。

// standard first call is pollQueue(uri, 0);
function pollQueue(uri, timesPolled, callback) {
    if(timesPolled > 28800) {
        // 288800 is (60 sec/min * 60 min/hr * 24 hr) / 3 sec/poll. Aka 24 hours.
        throw 'ResourceWillNeverBeReady';
    }

    console.log("polling " + uri);
    request({
      url: "http://localhost:2500/" + uri,
      followRedirect: false
    }, function (error, response, body) {
        if(response.statusCode === 303) {
            // callback handles requesting the actual data
            callback(response.headers.location); 
            return;
        }

        setTimeout(function() { pollQueue(uri, timesPolled + 1, callback);}, 3000);
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    相关资源
    最近更新 更多