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

Command icon 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

gabesullice created an issue. See original summary.

gabesullice’s picture

Assigned: Unassigned » gabesullice

gabesullice’s picture

Assigned: gabesullice » Unassigned
Status: Active » Needs review
gabesullice’s picture

Assigned: Unassigned » gabesullice
Status: Needs review » Active

Marking this as active again and assigning myself because I may have misunderstood the problem.

gabesullice’s picture

Status: Active » Closed (works as designed)

The underlying issue for me was that the workspace cache context is not added to responses that don't go through the renderer even if an active workspace contributed to the CacheableResponse. That means the responsibility of adding the cache context is on each custom controller.

The solution for me was to add the _has_active_workspace route requirement, which has the effect of adding the workspace cache context to the response.

Part of what misled me was that WorkspaceCacheContext::getCacheableMetadata() unnecessarily adds the session context. However, since the workspace is a "root" cache context—i.e. it is never optimized away—getCacheableMetadata() is never called and the session context is never needed.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.