Summary
When a grid of experiments is submitted as a single slurm job array (via TaskInfra.job_array()), and each job independently accesses a shared cached step (same folder) that computes a large set of items, exca's cachedict inflight registry sqlite database gets corrupted:
sqlite3.DatabaseError: file is not a database
The corruption then cascades into FileNotFoundError on full-uid.yaml and submitit.core.utils.UncompletedJobError for the sub-tasks, failing the whole run.
Environment
- exca
0.5.27
- Python 3.12, Linux, slurm cluster (submitit backend)
Scenario
- ~18 experiments submitted together via
TaskInfra.job_array().
- Each job calls into the same shared cached pipeline (a
Cached step backend + a map that computes ~432 items) pointing at the same cache folder.
- All ~18 jobs start ~simultaneously, so many concurrently query/populate the same inflight registry.
- Pre-warming the cache once (single builder) before submitting the array does not prevent it: the concurrent jobs still re-open/validate the shared registry and corrupt it.
Stacktrace
WARNING - exca.cachedict.inflight:349 - Waiting for 432 in-flight items (of 432 requested) held by: <jobid> [slurm:RUNNING] x432
WARNING - exca.cachedict.registry:234 - Inflight registry query: file is not a database
Traceback (most recent call last):
File ".../exca/cachedict/registry.py", line 222, in _safe_execute
return self._retry_on_lock(run)
File ".../exca/cachedict/registry.py", line 130, in _retry_on_lock
return fn()
File ".../exca/cachedict/registry.py", line 211, in run
return fn(conn)
File ".../exca/cachedict/inflight.py", line 316, in _do
rows = registry.select_in_chunks(
File ".../exca/cachedict/registry.py", line 49, in select_in_chunks
out.extend(conn.execute(sql, batch).fetchall())
sqlite3.DatabaseError: file is not a database
Also observed alongside it:
FileNotFoundError: [Errno 2] No such file or directory: '.../<cache-uid>/full-uid.yaml'
submitit.core.utils.UncompletedJobError: Job <jobid> (task: 0) with path .../logs/<jobid>/<jobid>_0_result.pkl
Expected
Concurrent readers/writers of a shared cachedict (typical when a job array shares one cache folder) should not corrupt the sqlite inflight registry. Either serialize/guard registry writes robustly across processes, tolerate concurrent access, or fail loudly with a clear message instead of silently corrupting the DB.
Notes
Happy to help repro. Workaround we used: disable the Slurm timelines sub-infra so items are computed in-process (removing the concurrent writers to that registry).
Summary
When a grid of experiments is submitted as a single slurm job array (via
TaskInfra.job_array()), and each job independently accesses a shared cached step (samefolder) that computes a large set of items, exca's cachedict inflight registry sqlite database gets corrupted:The corruption then cascades into
FileNotFoundErroronfull-uid.yamlandsubmitit.core.utils.UncompletedJobErrorfor the sub-tasks, failing the whole run.Environment
0.5.27Scenario
TaskInfra.job_array().Cachedstep backend + a map that computes ~432 items) pointing at the same cachefolder.Stacktrace
Also observed alongside it:
Expected
Concurrent readers/writers of a shared cachedict (typical when a job array shares one cache folder) should not corrupt the sqlite inflight registry. Either serialize/guard registry writes robustly across processes, tolerate concurrent access, or fail loudly with a clear message instead of silently corrupting the DB.
Notes
Happy to help repro. Workaround we used: disable the
Slurmtimelines sub-infra so items are computed in-process (removing the concurrent writers to that registry).