Problem/Motivation
Problem/Motivation
Drupal core's WorkspaceCacheContext::getCacheableMetadata() hardcodes addCacheContexts(['session']). This is correct for the default SessionWorkspaceNegotiator, but wse ships two negotiators that determine the active workspace through different mechanisms:
- CookieWorkspaceNegotiator (wse_preview) reads the workspace from a wse_preview cookie
- JsonApiWorkspaceNegotiator (wse_deploy) reads the workspace from a Workspace query parameter
For requests handled by these negotiators, dynamic_page_cache varies responses by session instead of the actual cache dependency (cookies:wse_preview or url.query_args:Workspace). This can cause incorrect cache results. For example, users being apparently unable to switch between workspace previews.
Proposed resolution
Add a CacheableWorkspaceIdNegotiatorInterface to wse with a single method:
public function getCacheableMetadata(): CacheableMetadata;
And decorate core's cache_context.workspace in wse. The decorator collects workspace_negotiator-tagged services like workspaces.manager and, on getCacheableMetadata(), iterates to find the one that applies to the current request. If that negotiator implements CacheableWorkspaceIdNegotiatorInterface, its metadata is returned directly. Otherwise, the decorator falls back to the inner (core) context's metadata, preserving backward compatibility for any negotiator that does not implement the new interface.
CookieWorkspaceNegotiator and JsonApiWorkspaceNegotiator in wse_preview and wse_deploy are updated to implement the interface, returning cookies:wse_preview and url.query_args:Workspace respectively.
User interface changes
n/a
API changes
A new CacheableWorkspaceIdNegotiatorInterface is introduced.
Data model changes
n/a
Issue fork wse-3586738
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gabesulliceComment #4
gabesulliceComment #5
gabesulliceMarking this as active again and assigning myself because I may have misunderstood the problem.
Comment #6
gabesulliceThe underlying issue for me was that the
workspacecache context is not added to responses that don't go through the renderer even if an active workspace contributed to theCacheableResponse. That means the responsibility of adding the cache context is on each custom controller.The solution for me was to add the
_has_active_workspaceroute requirement, which has the effect of adding theworkspacecache context to the response.Part of what misled me was that
WorkspaceCacheContext::getCacheableMetadata()unnecessarily adds thesessioncontext. However, since theworkspaceis a "root" cache context—i.e. it is never optimized away—getCacheableMetadata()is never called and thesessioncontext is never needed.