Repository: DataBiosphere/toil

Issue:
getRunningBatchJobIDs raises "RuntimeError: dictionary changed size during iteration"
```
Traceback (most recent call last):
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/test/sort/sortTest.py", line 229, in testFileSingle10000
    lines=10000, N=10000)
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/test/sort/sortTest.py", line 143, in _toilSort
    toil.restart()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/common.py", line 700, in restart
    return self._runMainLoop(rootJobGraph)
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/common.py", line 984, in _runMainLoop
    jobCache=self._jobCache).run()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 175, in run
    self.innerLoop()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 475, in innerLoop
    self.checkForDeadlocks()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 492, in checkForDeadlocks
    totalRunningJobs = len(self.batchSystem.getRunningBatchJobIDs())
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/batchSystems/singleMachine.py", line 234, in getRunningBatchJobIDs
    return {jobID: now - info.time for jobID, info in iteritems(self.runningJobs)}
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/batchSystems/singleMachine.py", line 234, in <dictcomp>
    return {jobID: now - info.time for jobID, info in iteritems(self.runningJobs)}
RuntimeError: dictionary changed size during iteration
```

Seen here: http://jenkins.cgcloud.info/job/toil-pull-requests/2681/testReport/junit/src.toil.test.sort.sortTest/SortTest/testFileSingle10000/
getRunningBatchJobIDs raises "RuntimeError: dictionary changed size during iteration"
```
Traceback (most recent call last):
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/test/sort/sortTest.py", line 229, in testFileSingle10000
    lines=10000, N=10000)
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/test/sort/sortTest.py", line 143, in _toilSort
    toil.restart()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/common.py", line 700, in restart
    return self._runMainLoop(rootJobGraph)
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/common.py", line 984, in _runMainLoop
    jobCache=self._jobCache).run()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 175, in run
    self.innerLoop()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 475, in innerLoop
    self.checkForDeadlocks()
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/leader.py", line 492, in checkForDeadlocks
    totalRunningJobs = len(self.batchSystem.getRunningBatchJobIDs())
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/batchSystems/singleMachine.py", line 234, in getRunningBatchJobIDs
    return {jobID: now - info.time for jobID, info in iteritems(self.runningJobs)}
  File "/mnt/ephemeral/workspace/toil-pull-requests/src/toil/batchSystems/singleMachine.py", line 234, in <dictcomp>
    return {jobID: now - info.time for jobID, info in iteritems(self.runningJobs)}
RuntimeError: dictionary changed size during iteration
```

Seen here: http://jenkins.cgcloud.info/job/toil-pull-requests/2681/testReport/junit/src.toil.test.sort.sortTest/SortTest/testFileSingle10000/


Discussion:

Resolving patch:
diff --git a/src/toil/batchSystems/singleMachine.py b/src/toil/batchSystems/singleMachine.py
--- a/src/toil/batchSystems/singleMachine.py
+++ b/src/toil/batchSystems/singleMachine.py
@@ -26,7 +26,6 @@
 # Python 3 compatibility imports
 from six.moves.queue import Empty, Queue
 from six.moves import xrange
-from six import iteritems
 
 import toil
 from toil.batchSystems.abstractBatchSystem import BatchSystemSupport, InsufficientSystemResources
@@ -231,7 +230,7 @@ def getIssuedBatchJobIDs(self):
 
     def getRunningBatchJobIDs(self):
         now = time.time()
-        return {jobID: now - info.time for jobID, info in iteritems(self.runningJobs)}
+        return {jobID: now - info.time for jobID, info in self.runningJobs.items()}
 
     def shutdown(self):
         """


Test patch: