Race Condition in StoryManager prevents it waiting for all tasks to be done
Description
In waitUntilAllDoneOrFailed() method in StoryManager Class, inside while loop we are iterating a HashMap (runningStories) in a for each loop.
Since we are using a HashMap, order is not guaranteed over time, and thus there's a chance to exit prematurely the while loop, if:
There is no in progress task, i.e. all tasks are either done or not started (or marked as that).
Last task is done.
This exists the while loop, without waiting for all task to finish.
Activity
Show:
Mauro Talevi March 17, 2016 at 7:01 PM
Pulled with thanks.
RafaelJ March 17, 2016 at 1:47 PM
Edited
We could change runningStories from HashMap to LinkedHashMap, however we could have problems with custom ExecutorService implementations, since they may not use a FIFO queue as in default ExecutorService used by JBehave.
Rather than trusting a specific execution order, I am changing the logic so that if a story hasn't started yet, allDone flag is set to false too. This will cause an extra iteration over the loop, causing a very small performance degradation. However we should improve it by not updating always failures Map whenever the task is done.
In addition, I am marking the story as started as early as possible.
In waitUntilAllDoneOrFailed() method in StoryManager Class, inside while loop we are iterating a HashMap (runningStories) in a for each loop.
Since we are using a HashMap, order is not guaranteed over time, and thus there's a chance to exit prematurely the while loop, if:
There is no in progress task, i.e. all tasks are either done or not started (or marked as that).
Last task is done.
This exists the while loop, without waiting for all task to finish.