xjq233p_1
xjq233p_1

Reputation: 8060

Nodejs Testing. How to avoid Race Conditions?

I am currently writing a game engine in nodejs.

My game has several states. Let's call them StateA, StateB, StateC. The flow of sequence is StateA => StateB => StateC.

I would like to test the state of my engine at the end of each state. I currently have this structure:

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)
}

So my current approach involves having my test cases override stateXCallback and executing the testing logic in those functions.

However, I am seeing a race condition where stateB is fired before stateACallBack has finished executing. As a result, stateACallback is seeing states that should be evaluated by stateBCallback instead.

I tried injecting a delay time between the states, however, this introduces additional race condition bugs in my codebase.

Can someone please enlighten me a better approach to this problem?

Upvotes: 2

Views: 1175

Answers (1)

Tark
Tark

Reputation: 5173

It is pretty hard to discuss this in such an abstract manner, but it seems to me that what you are calling states are not really states, they are asynchronous events. Each of these events may change the internal state of the state machine, but that depends on the order in which event is received. I am not sure if the only trigger for event B is event A, but I am assuming not. (If it is, then why split the events up into separate events A, B and C? Seems arbitrary and pointless, why not just call each callback in turn?).

So, to implement the state machine, somewhere you need a variable that tracks the current state the machine is in. When an event is received, the callback has to decide whether to consume the event and advance the state machine, or to put it in a queue and wait until the machine is in a different state.

If you want more detail, or a more accurate answer, you are going to have to tell me what these events are and what is triggering them.

Upvotes: 1

Related Questions