Retry HDF5 opens on transient file-lock failures (fixes zoomify --balance -p N>1 on NFS) - #488
Open
treznicek wants to merge 1 commit into
Open
Retry HDF5 opens on transient file-lock failures (fixes zoomify --balance -p N>1 on NFS)#488treznicek wants to merge 1 commit into
treznicek wants to merge 1 commit into
Conversation
Zoomify hdf5 file lock contention with multithreading across resolutions Added a helper to catch BlockingIOError if overloaded and retry after sleep. Switched from h5py.File() to the new helper to preven blocking error. Added docs note HDF5_USE_FILE_LOCKING=FALSE workaround. Added tests to validate retry behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
cooler zoomify --balance -p N(N > 1) intermittently fails on NFS-mountedfilesystems with
BlockingIOError: [Errno 11] ... unable to lock file, raisedfrom
h5py.File(cool_path, 'r+')incli/balance.py.-p 1avoids it.Diagnosis
The issue suggests multiple zoom levels are balanced concurrently. That doesn't
appear to be what's happening — the relevant loops are all strictly sequential:
zoomify()runszoomify_cooler()to completion, and only then callsinvoke_balance()(cli/zoomify.py).invoke_balance()balances resolutions one at a time, callingbalance_cmd.main()in-process and waiting for each to finish.zoomify_cooler()likewise coarsens resolutions in a plain sequential loop.So two zoom levels are never in flight at once, and the only writer is always
the parent process.
What
-p N > 1does introduce is multi-process access to the same file:coarsen_cooler()forks anmp.Poolwhose workers open the file read-only,while the parent periodically opens it
'r+'to write. With-p 1no pool iscreated at all (builtin
mapis used), so no second process ever touches thefile — which is why the workaround works.
This is aggravated by
write_pixels()opening and closing the output file onceper chunk, i.e. one lock acquire/release cycle per chunk. The finest resolution
has the most chunks, which matches the report that it fails on the largest
resolution level. On NFS, where
flock()semantics are frequently unreliable,that lock acquisition can fail transiently even though cooler's own
multiprocess.Lockcorrectly prevents any actual read/write race.Fix
Add
open_hdf5_with_retry()incooler/util.py: a drop-inh5py.Filereplacement that retries with exponential backoff on
BlockingIOErrorandre-raises once attempts are exhausted. Applied to the write-path opens
exercised by
zoomify --balance:create/_create.py—write_pixels()and all opens increate()cli/balance.py— all three opens, including the one in the reported tracebackAlso documents
HDF5_USE_FILE_LOCKING=FALSEin thezoomify/balancehelptext as an immediate workaround.
Deliberately not included
This is a targeted mitigation, not a fix for the underlying lock churn. Holding
a single file handle open across
write_pixels()'s whole write loop, instead ofreopening per chunk, would reduce lock acquisitions at the source — but that
touches a performance-sensitive path and felt out of scope here. It's noted as
follow-up work in a code comment and in CHANGES.md.
Testing
failures; re-raise after exhaustion).
on a real NFS mount would be valuable.
Fixes #486
Generated with Claude Code