Skip to content

Existence cache remove callbacks - #1947

Merged
palfrey merged 17 commits into
TraceMachina:mainfrom
palfrey:existence-cache-remove-callbacks
Oct 3, 2025
Merged

palfrey merged 17 commits into
TraceMachina:mainfrom
palfrey:existence-cache-remove-callbacks

Conversation

@palfrey

@palfrey palfrey commented Oct 2, 2025 •

Copy link
Copy Markdown
Member

Description

There's an issue with the existence cache if one or more of it's underlying stores evicts items. Namely, when they do so, they don't tell anyone about it, and so the existence cache still says "yup, got that" and then clients will fail when they try to retrieve the item. This is believed (but not certain) as the source of the not found in either fast or slow store errors that have been cropping up. This PR adds a callback mechanism for evictions so compound stores that need to know about their inner stores evicting things can get notified.

Consequences of this change:

  • Various configs that were previously regarded as valid are no longer, primarily existence caches with GrpcStore as an internal store, as we don't get "I evicted this" feedback from those. These will now fail at runtime.
  • The EvictingMap type has become more complicated to support using the borrow key there as the callback key.

Type of change

Please delete options that aren't relevant.

  • Breaking change (fix or feature that would cause existing functionality to
    not work as expected)

How Has This Been Tested?

bazel test //...

Checklist

  • Updated documentation if needed
  • Tests added/amended
  • bazel test //... passes locally
  • PR is contained in a single commit, using git amend see some docs

This change is Reviewable

Comment on lines +35 to +37
impl RemoveStateCallback<StoreKey<'static>> for RemoveItemCallbackHolder {
async fn callback(&self, key: &StoreKey<'static>) {
self.callback_fn.callback(key).await;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The RemoveItemCallback trait could use a module-level doc comment explaining its purpose (e.g., "For notifying caches of deletions from backing stores").

It's a pretty big piece of functionality.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup, I'll add a few doc comments to the various new traits tomorrow.

// as if it immediately expires them, we should only apply the remove callbacks
// afterwards. If this is None, we're not pausing; if it's Some it's the location to
// store them in temporarily
pause_remove_callbacks: Arc<Mutex<Option<Vec<StoreKey<'static>>>>>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are paused callbacks still flushed if an update fails mid way?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes. The update is in two phases - inner store and then the existence cache - and both don't do any returns of errors until after the pause_remove_callbacks has been reset.

Comment thread nativelink-store/src/shard_store.rs Outdated
// Bucket each key into the store that it belongs to.
keys.iter()
.cloned()
.cloned()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not blaming you because it was here for almost two years. It think we could be more efficient than .cloned().enumerate(). The only reason I would even bring it up is the fact that shard_store really only matters for large workloads.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Removed now the 'static fixes are done.

async fn get_part(
self: Pin<&Self>,
key: StoreKey<'_>,
key: StoreKey<'static>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you explain this change to me? No fault of your own, btw.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wasn’t suggesting you change. I wanted to know what was the rationale, mostly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It was always one of those changes that I wasn't entirely happy with, but I thought it was needed in order to support some part of the evicting map changes. It turns out that I think it was needed earlier on, but not anymore, so I've been able to reset this.

@MarcusSorealheis MarcusSorealheis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

there's a lot of code to read and try out. I'll add more comments in a bit but wanted to get some comments to you now.

Comment thread .bazelrc
# ThreadSanitizer to detect data races. Tests under tsan shouldn't be cached
# since they tend to produce irreproducible false negatives.
build:tsan --config=nightly -c dbg
build:tsan --config=nightly --config=debug

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same effect, but clearer

This branch was previously deployed

1 inactive deployment
production — 93d4bc7d Deployed Oct 3, 2025 by palfrey via NativeLink.com Cloud / Remote Cache / ubuntu-24.04 #660
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.

2 participants