esitarski / CrossMgr

Cyclo Cross Management Application
MIT License
40 stars 20 forks source link

SeriesMgr: SetNoDataDNS() backward compatibility issue? #133

Open kimble4 opened 5 months ago

kimble4 commented 5 months ago

I can't easily test this one with the official build, as my offending race files aren't fully compatible, but on the basis that you've probably got the same issue:

I'm finding that loading old race files (where some riders in the sign-on sheet have no data) into SeriesMgr will cause exceptions like this (your line numbers may vary):

Exception in thread refreshResultsBackground:
multiprocessing.pool.RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/SeriesModel.py", line 37, in __call__
    return memoize.cache[self.func.__name__][args]
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
KeyError: '_extractAllRaceResultsCore'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/Model.py", line 63, in __call__
    return memoize.cache[self.func.__name__][args]
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
KeyError: 'GetResultsWithData'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
                    ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/multiprocessing/pool.py", line 51, in starmapstar
    return list(itertools.starmap(args[0], args[1]))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/GetModelInfo.py", line 174, in ExtractRaceResults
    return ExtractRaceResultsCrossMgr( r, seriesModel )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/GetModelInfo.py", line 411, in ExtractRaceResultsCrossMgr
    results = GetResults( category )
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/GetResults.py", line 829, in GetResults
    return GetResultsWithData( category )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/Model.py", line 66, in __call__
    value = self.func(*args)
            ^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/GetResults.py", line 728, in GetResultsWithData
    return GetNonWaveCategoryResults( category )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/GetResults.py", line 643, in GetNonWaveCategoryResults
    for num in race.getRiderNums():
RuntimeError: dictionary changed size during iteration
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.11/threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/MainWin.py", line 951, in backgroundRefresh
    raceResults = model.extractAllRaceResults()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/SeriesModel.py", line 664, in extractAllRaceResults
    raceResults = self._extractAllRaceResultsCore()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/SeriesModel.py", line 39, in __call__
    value = self.func(*args)
            ^^^^^^^^^^^^^^^^
  File "/mnt/kim/documents/programming/CrossMgrGitHub/CrossMgr/SeriesMgr/SeriesModel.py", line 644, in _extractAllRaceResultsCore
    p_results = p.starmap( GetModelInfo.ExtractRaceResults, ((r,self) for r in self.races) )
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/multiprocessing/pool.py", line 375, in starmap
    return self._map_async(func, iterable, starmapstar, chunksize).get()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/multiprocessing/pool.py", line 774, in get
    raise self._value
RuntimeError: dictionary changed size during iteration

The underlying problem appears to be that GetNonWaveCategoryResults() calls GetResults() while iterating over the keys returned by race.getRiderNums().

As GetResults() calls GetResultsWithData() which calls _GetResultsCore() which calls SetNoDataDNS() which calls race.getRider(), which adds a new rider to the race.riders dictionary if the rider does not exist, this results in a modification of race.riders while it is being iterated over. Clear as mud.

Changing:

for num in race.getRiderNums():

in GetNonWaveCategoryResults() to:

for num in list(race.getRiderNums()):

Appears to solve the specific problem, but this may not be a good general solution?

(As a work-around, you can open the race in CrossMgr and set the offending riders to DNS before loading into SeriesMgr.)