Skip to content

forceDerivation(): Wait for async path write after forcing value#176

Merged
edolstra merged 2 commits intomainfrom
fix-eval-cache-async-path
Aug 19, 2025
Merged

forceDerivation(): Wait for async path write after forcing value#176
edolstra merged 2 commits intomainfrom
fix-eval-cache-async-path

Conversation

@edolstra
Copy link
Collaborator

Motivation

If the drv attribute exists in the eval cache but the drv does not exist in the Nix store, then the drv may not exist immediately after the call to forceValue(). So we have to synchronize there.

Fixes a bug introduced in #162.

Context

If the drv attribute exists in the eval cache but the drv does not
exist in the Nix store, then the drv may not exist immediately after
the call to forceValue(). So we have to synchronize there.
@edolstra edolstra enabled auto-merge August 18, 2025 19:38
@github-actions
Copy link

github-actions bot commented Aug 18, 2025

@github-actions github-actions bot temporarily deployed to pull request August 18, 2025 19:40 Inactive
auto aDrvPath = getAttr(root->state.sDrvPath);
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
drvPath.requireDerivation();
root->state.waitForPath(drvPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really qualified to review this, but I'm curious - why did you move this line and not duplicate it?

Is there no chance that requireDerivation might also require waiting, and would otherwise avoid having to forceValue if you had waited?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my other comment.

auto aDrvPath = getAttr(root->state.sDrvPath);
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
drvPath.requireDerivation();
root->state.waitForPath(drvPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens right now, with the waitForPath here? (I guess my real question is: what does this really fix? It seems like waitForPath is now being called in less cases than before, which may be fine and correct but seems weird for "calling it more times than necessary" to cause issues...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood it as the critical bit was needing to make sure there's a wait after calling aDrvPath->forceValue();. I'm likely hitting the case in the comment - the nix eval cache is shared between CI runs, and occasionally I manually run GC on the box.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original waitForPath() was basically pointless, because it waits before the attribute has been evaluated. So at that point, the asynchronous creation of store paths (the .drv file and its dependencies) hasn't even started yet.

In the common case where the attribute is cached and the corresponding .drv file exists in the store, there is no need to wait for anything. And if the .drv file has been GC'ed, we need to evaluate the attribute to recreate it and then wait.

the nix eval cache is shared between CI runs, and occasionally I manually run GC on the box.

Right, this bug triggers if the eval cache gets out of sync with what's in the store.

@github-actions github-actions bot temporarily deployed to pull request August 19, 2025 11:02 Inactive
@edolstra
Copy link
Collaborator Author

Added a test.

@edolstra edolstra force-pushed the fix-eval-cache-async-path branch from 4b0ec85 to 07ed0a2 Compare August 19, 2025 11:11
@github-actions github-actions bot temporarily deployed to pull request August 19, 2025 11:13 Inactive
@edolstra edolstra added this pull request to the merge queue Aug 19, 2025
Merged via the queue into main with commit a85ebbc Aug 19, 2025
33 checks passed
@edolstra edolstra deleted the fix-eval-cache-async-path branch August 19, 2025 15:02
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.

3 participants