Skip to content

Cache purge stub#6465

Open
tewaro wants to merge 2 commits intomainfrom
atewari/purge-jsrpc
Open

Cache purge stub#6465
tewaro wants to merge 2 commits intomainfrom
atewari/purge-jsrpc

Conversation

@tewaro
Copy link
Copy Markdown
Contributor

@tewaro tewaro commented Mar 31, 2026

No description provided.

@tewaro tewaro requested review from a team as code owners March 31, 2026 15:51
Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

I'm Bonk, and I've done a quick review of your PR.

This PR adds a ctx.cache stub property to ExecutionContext, delegating to a virtual Worker::Api::getCtxCacheProperty() hook that returns undefined by default.

Issues (highest severity first):

  1. [HIGH] New ctx.cache property is unconditionally exposed with no compat flag or autogate. Adding a new property to every ExecutionContext instance is a behavioral change — it could shadow user-defined cache properties or break code that checks 'cache' in ctx. Other ctx properties (exports, version, abort) are all gated behind compat flags. This needs at minimum a compat flag or autogate for staged rollout.
  2. [MEDIUM] No tests. There are no tests covering the new getCache() path or the getCtxCacheProperty() hook.
  3. [LOW] Missing TypeScript type definition. The JSG_TS_OVERRIDE blocks in JSG_RESOURCE_TYPE don't include cache, so generated TypeScript types won't reflect this property.
  4. [LOW] Comment inaccuracies. Minor comment issues flagged inline.

These comments were generated by an AI code review assistant and may not be perfect. Please use your judgment when evaluating them.

JSG_LAZY_INSTANCE_PROPERTY(exports, getExports);
}
JSG_LAZY_INSTANCE_PROPERTY(props, getProps);
JSG_LAZY_INSTANCE_PROPERTY(cache, getCache);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] This property is registered unconditionally, meaning every worker will see ctx.cache. Other ctx properties like exports (line 249-251), version (line 254-256), and abort (line 269) are all gated behind compat flags.

Adding a new enumerable property to a widely-used object without a gate is a backward-compat risk — it can break code that does 'cache' in ctx checks or Object.keys(ctx) assertions. This should be gated behind a compat flag or at minimum an autogate for staged rollout.

Suggested change
JSG_LAZY_INSTANCE_PROPERTY(cache, getCache);
// TODO(cleanup): Gate behind a compat flag once the feature is ready.
// JSG_LAZY_INSTANCE_PROPERTY(cache, getCache);

(The suggestion above is just illustrative — in practice you'd wrap this in an if (flags.getSomeNewFlag()) { ... } block like the other properties.)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@jasnell we don't want ctx.cache to be based on a compat flag, we want it to be based on a config option, namely CacheConfig.enabled = true in the internal worker config (or maybe in the future the workerd config).
Is there a way to sort this so that ctx.cache is "not defined" in that scenario rather than "undefined"?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

That's a bit tricky here. We don't expose any mechanism currently to access the worker configuration at this point in the registration. Would have to solve that limitation first.

return props.getHandle(js);
}

// Returns an optional cache object for CacheW-enabled workers.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[LOW] "CacheW-enabled" looks like a typo — did you mean "Cache-enabled"?

Also, the comment says "Overridden via IoChannelFactory" but the actual override mechanism is through Worker::Api subclassing (the virtual getCtxCacheProperty() method). The comment should reflect the actual design.

Suggested change
// Returns an optional cache object for CacheW-enabled workers.
// Returns an optional cache object for cache-enabled workers.
// The default implementation returns undefined. Overridden via Worker::Api.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah bonk is right, seems like an odd typo.

IoContext::current().setFailOpen();
}

jsg::JsValue ExecutionContext::getCache(jsg::Lock& js) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[LOW] The IoContext::hasCurrent() guard means this silently returns undefined when called outside of request context. This is consistent with the pattern for a lazy property getter, but worth noting: if the embedding override returns a JS object (not undefined), the caller might be surprised that ctx.cache is undefined in some code paths (e.g., module top-level evaluation). Consider adding a brief comment explaining when this fallback triggers.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 31, 2026

Review posted successfully on PR #6465. Here's a summary of the findings:

  1. [HIGH] No compat flag or autogate: The ctx.cache property is unconditionally exposed to all workers. Other ctx properties (exports, version, abort) are all gated behind compat flags. This is a backward-compat risk since it adds a new enumerable property to every ExecutionContext.

  2. [MEDIUM] No tests: No tests cover the new code paths.

  3. [LOW] Missing TypeScript types: The JSG_TS_OVERRIDE blocks don't include cache.

  4. [LOW] Comment inaccuracies: "CacheW-enabled" typo and incorrect reference to IoChannelFactory (should be Worker::Api).

github run

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

The generated output of @cloudflare/workers-types matches the snapshot in types/generated-snapshot 🎉

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.90%. Comparing base (2ed69c4) to head (18b1c66).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
src/workerd/api/global-scope.c++ 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6465      +/-   ##
==========================================
- Coverage   70.95%   70.90%   -0.05%     
==========================================
  Files         428      428              
  Lines      119850   119943      +93     
  Branches    18988    19003      +15     
==========================================
+ Hits        85037    85048      +11     
- Misses      23529    23606      +77     
- Partials    11284    11289       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tewaro tewaro requested a review from a team as a code owner March 31, 2026 16:44
@tewaro tewaro requested a review from vicb March 31, 2026 16:44
JSG_METHOD(abort);
}

// TODO(soon): This is getting unwieldy.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ctx.cache is missing in the types override

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.

4 participants