【问题标题】:Nodejs Testing. How to avoid Race Conditions?节点测试。如何避免竞争条件?
【发布时间】:2012-03-24 16:58:11
【问题描述】:

我目前正在用 nodejs 编写游戏引擎。

我的游戏有几个状态。我们称它们为 StateA、StateB、StateC。序列的流程是StateA => StateB => StateC。

我想在每个状态结束时测试我的引擎的状态。我目前有这个结构:

function attachEventListeners = function(instance) {
  instance.on('START_STATE_A', stateA);
  instance.on('START_STATE_B', stateB);
  instance.on('START_STATE_C', stateC);
}

var stateACallBack = function() {};
var stateBCallBack = function() {};
var stateCCallBack = function() {};

function stateA() { 
  // Do something...
  stateACallBack();
  setTimeout(function() { this.emit('START_STATE_B'); }, 3000)
}

function stateB() { 
  // Do something...
  stateBCallBack();
  setTimeout(function() { this.emit('START_STATE_C'); }, 3000)
}

function stateC() { 
  // Do something...
  stateCCallBack();
  setTimeout(function() { this.emit('START_STATE_A'); }, 3000)
}

所以我目前的方法是让我的测试用例覆盖 stateXCallback 并在这些函数中执行测试逻辑。

但是,我看到 stateB 在 stateACallBack 完成执行之前被触发的竞争条件。因此,stateACallback 看到的是应该由 stateBCallback 评估的状态。

我尝试在状态之间注入延迟时间,但是,这会在我的代码库中引入额外的竞争条件错误。

有人可以告诉我解决这个问题的更好方法吗?

【问题讨论】:

    标签: testing node.js


    【解决方案1】:

    很难以如此抽象的方式讨论这个问题,但在我看来,你所说的状态并不是真正的状态,它们是异步事件。这些事件中的每一个都可能改变状态机的内部状态,但这取决于接收事件的顺序。我不确定事件 B 的唯一触发因素是否是事件 A,但我假设不是。 (如果是,那为什么要将事件拆分为单独的事件 A、B 和 C?看起来随意且毫无意义,为什么不依次调用每个回调?)。

    所以,要实现状态机,您需要一个变量来跟踪机器当前所处的状态。当接收到事件时,回调必须决定是使用该事件并推进状态机,还是将其放入队列中,等待机器处于不同的状态。

    如果您想了解更多细节或更准确的答案,您必须告诉我这些事件是什么以及触发它们的原因。

    【讨论】:

      猜你喜欢
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 2015-01-30
      • 2010-09-25
      • 2016-09-20
      相关资源
      最近更新 更多