Skip to content

Fix index file race conditions - #625

Merged
ugexe merged 4 commits into
mainfrom
ugexe/ecosystems-index-update-race
Sep 17, 2026
Merged

ugexe merged 4 commits into
mainfrom
ugexe/ecosystems-index-update-race

Conversation

@ugexe

@ugexe ugexe commented Sep 17, 2026

Copy link
Copy Markdown
Owner

No description provided.

Previously an update truncated the index file before locking it, and
every updating process fetched the mirror to the same path in the
store. When several zef processes started on a fresh store at the same
time, such as the parallel installs Blin runs, some of them read an
empty or partially written index. The parse error was swallowed, so
those processes reported "No candidates found matching identity" for
distributions that exist.

This fetches each mirror to a unique path that is removed afterwards,
and writes the index to a unique temporary file that is then renamed
over the index. Readers now see either the previous index or the
complete new one, so the lock files are no longer needed.
Previously an index that failed to parse was searched as an empty
ecosystem, so an install reported "No candidates found matching
identity" for distributions that exist. This reports the index and the
parse error instead.
Previously an update saved whatever a mirror responded with, so an
error page or a truncated response replaced a good index, and every
following install failed until the next update. A mirror is now parsed
before it replaces the index, and a mirror that does not parse is
passed over for the next one.

The iteration also kept going after a mirror was saved, leaving the
last mirror as the index rather than the first one that worked. It now
stops at the first mirror that provides a package list.

Populating the distributions reuses the package list that the update
parsed instead of reading the index back.
Previously the lock file was deleted once the protected code finished.
A process already waiting for it then took the lock on a file that no
longer had a name, while the next process created a new file and locked
that instead, so both ran the protected code at once.

This keeps the lock file. An ecosystem update now fetches into a
directory of its own so that the lock file the fetcher leaves behind is
removed along with everything else it fetched.
@ugexe
ugexe merged commit 74f446f into main Sep 17, 2026
6 checks passed
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