Skip to content

Release file locks on close failure and clarify path errors#265

Merged
rayosborn merged 2 commits into
nexpy:mainfrom
rayosborn:release-locks-on-error
Jun 4, 2026
Merged

Release file locks on close failure and clarify path errors#265
rayosborn merged 2 commits into
nexpy:mainfrom
rayosborn:release-locks-on-error

Conversation

@rayosborn

Copy link
Copy Markdown
Contributor

Summary

Two unrelated fixes bundled together.

Release file lock even if h5py close raises

NXFile.close() previously called release_lock() only if the preceding self._file.close() did not raise. An h5py flush error during close would therefore strand the .lock file on disk, blocking every subsequent acquire_lock() on the same file until the 8-hour expiry window kicked in. NXFile.__exit__ had the same shape: a raising close() left _with_count stuck at 1, so later with-blocks on the same NXFile skipped open() entirely and never retried the close.

Both are now wrapped in try/finally so the lock is always released and the counter always decrements. This was surfaced by an nxrefine workflow where a failed nxlink task left a stale .lock file behind, and subsequent nxmax runs on sibling entries blocked indefinitely on acquire_lock().

Include the offending key in NXgroup path-error messages

NXgroup.__getitem__ and __setitem__ raised NeXusError("Invalid index") / NeXusError("Invalid path") with no indication of which key triggered the failure. The messages now interpolate the offending key or resolved path so the caller can tell at a glance which lookup went wrong.

Test plan

  • Force an h5py close failure inside a with nxopen(file, 'rw'): block and confirm the .lock file is removed and _with_count returns to 0
  • Re-enter the same NXFile via a new with block after a simulated close failure and confirm it acquires the lock cleanly rather than skipping open()
  • Trigger NeXusError from NXgroup['/nonexistent/path'] and confirm the message includes the path
  • Existing test suite passes

rayosborn and others added 2 commits June 4, 2026 12:08
NeXusError messages for invalid indices and invalid paths in NXgroup
now interpolate the key or resolved path, so the caller can see which
lookup failed instead of just "Invalid path" / "Invalid index".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NXFile.close() called release_lock() unconditionally only if the
preceding self._file.close() did not raise; a flush error during
close would therefore strand the .lock file on disk and block every
subsequent acquire until the 8-hour expiry kicked in. NXFile.__exit__
had the same shape: a raising close() left _with_count stuck at 1,
so later with-blocks on the same NXFile would skip open() entirely
and never retry the close. Wrap both in try/finally so the lock is
always released and the counter always decrements.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rayosborn rayosborn merged commit 02dc70a into nexpy:main Jun 4, 2026
16 checks passed
@rayosborn rayosborn deleted the release-locks-on-error branch June 4, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant