处理连接丢失:重新执行请求或重新发送响应

时间:2016-11-21 06:17:30

标签: angularjs sails.js

使用angular-sails sailsjs后端通常以这种方式调用:

this.doSomethingWithItem = function(itemID, callback){
        $sails.put('/item/doSomething', {itemID:itemID}).
        success(function (data, status, headers, config) {
            callback(data);
        }).
        error(function (data, status, headers, config){
            alert('Error!');
        });
    };

在后端,大多数Sails(v0.11.0)控制器功能都相当简单。一个例子可能是这样的:

  doSomething: function(req, res) {
    var p = req.params.all();
    postgresClientPool.connect(function(err, client, done) {
      client.query("SELECT item_do_something_in_this_awesome_function($1) AS dbreturn", [p.itemID], function(err, result) {
      done();
      if(err) {
          res.status(500).json({success: false});
        }
      else {
          res.json(result.rows[0].dbreturn[0]);
       }
    });
  });
 }

现在由于某些原因,我们无法影响我们经历频繁但相当短的连接损失(在Client / Browser和nodeJS / sails-Server之间)。现在的任务是尽可能顺利地处理它们并避免任何进一步的不便。

因此,如果在正在进行的请求期间连接中断,则逻辑必须类似于:

  • 检查请求到达服务器之前或之后是否发生了连接中断。
  • 如果之前发生过:重新执行请求。
  • 如果事后发生:告诉后端重新发送请求的结果。

现在,如何实现这一目标?

我不知道在每个服务功能中注册$sails.on('disconnect'...是否是最好的主意。无论如何,我还没有弄清楚在函数执行完毕后如何取消注册它们。

1 个答案:

答案 0 :(得分:1)

首先,我建议您将业务逻辑从控制器中分离出来。

您可以查看其他答案:sails.js access controller method from controller method

通过这样做,您可以实际从控制器再次拨打电话,而无需做太多。

此外,我们将使用async模块中的async.retry和async.apply函数。

例如,假设您将代码移到api/services/CustomerService.js ex:

中的服务
module.exports = {
    get: function (customerId, done) {
        // postgresClientPool should be available in a param or globally?
        // I'd prefer assigning it to the sails object...
        // and use it like sails.postgresClientPool
        postgresClientPool.connect(function (err, client, release) {
          if (err) {
            release();
            done(err);
          }
          client.query("SELECT getCustomer($1) AS dbreturn", [customerId],
            function (err, result) {
              release();
              if (err) {
                done(err);
              } else {
                done(undefined, result.rows[0].dbreturn[0]);
              }
            });
        });
      }
    };

然后,在您的控制器中,例如api/controllers/Customer.js

get: function (req, res) {
    var p = req.params.all();
    async.retry(3, async.apply(CustomerService.get, p.customerID), function (err, result) {
      if (err) {
        res.status(500).json({
          success: false
        });
      } else {
        res.json(result);
      }
    })
  }

您应该在控制器顶部要求异步。