Background
This issue was raised during review of PR #4 (#4 (comment)) by @attakei.
Summary
In src/atsphinx/lindera/splitter.py, the SystemDictionary.fetch() method downloads and extracts a dictionary ZIP into self.local_path. If two sphinx-build processes run concurrently against the same user cache directory (e.g. in CI matrix builds or parallel documentation builds), one process could observe a partially extracted dictionary and proceed with corrupted data.
Current behavior
fetch() checks self.local_path.exists() and skips download if it does. However, extraction is not atomic: a second process could pass the existence check while the first is still extracting.
Proposed improvement
Extract into a temporary sibling directory, then atomically rename/move it to self.local_path only after zip.extractall completes. Clean up the temporary directory on failure.
Notes
In typical usage, fetch() is called once per sphinx-build invocation and users rarely run multiple builds concurrently for a single document. This is therefore a low-priority hardening task.
Requested by: @attakei
Background
This issue was raised during review of PR #4 (#4 (comment)) by @attakei.
Summary
In
src/atsphinx/lindera/splitter.py, theSystemDictionary.fetch()method downloads and extracts a dictionary ZIP intoself.local_path. If twosphinx-buildprocesses run concurrently against the same user cache directory (e.g. in CI matrix builds or parallel documentation builds), one process could observe a partially extracted dictionary and proceed with corrupted data.Current behavior
fetch()checksself.local_path.exists()and skips download if it does. However, extraction is not atomic: a second process could pass the existence check while the first is still extracting.Proposed improvement
Extract into a temporary sibling directory, then atomically rename/move it to
self.local_pathonly afterzip.extractallcompletes. Clean up the temporary directory on failure.Notes
In typical usage,
fetch()is called once persphinx-buildinvocation and users rarely run multiple builds concurrently for a single document. This is therefore a low-priority hardening task.Requested by: @attakei