Problem/Motivation

orchestra_token, orchestra_instance, orchestra_variable and orchestra_work_item are declared without persistent_cache, which defaults to TRUE, so their loads go through the persistent entity cache bin (memcache, redis or the database, depending on the site).

These are not read-mostly rows. The engine reads a token's state, decides from it (advance, park, consume, fire a join) and writes that decision back, often in the same millisecond. A stale read there does not merely display something old, it produces a wrong write: a token consumed with no successor, an instance completed while the entity it drives stays behind. A transient cache inconsistency becomes permanent corruption.

The exposure is real on any site whose cache bins live outside the database transaction (a shared memcache or redis server): cache writes and tag invalidations do not participate in commit or rollback, and concurrent workers (a web request, a queue worker draining an advance, an operator acting on a task) read and write the same rows.

There is also little to weigh against it. Each of these types is a single base table with a handful of columns, no revisions and no translations, so a load is one cheap query, while writes happen on nearly every step: the cache is churned as fast as it is filled.

Proposed resolution

Set persistent_cache: FALSE on the four runtime entity types. The per-request static cache still applies, only the persistent bin is bypassed: ContentEntityStorageBase::getFromPersistentCache() and setPersistentCache() both return early on the flag.

Leave orchestra_workflow_version cached: its snapshots are immutable once written, which is what a persistent cache is for. orchestra_incident is an open question, it is mutated but not in the advance path.

Whether an advance should additionally hold a per-instance lock and re-read state inside it is a separate concern, worth a follow-up if the advance path proves unguarded; the module already locks in WorkItemManager and WorkflowVersionManager.

Remaining tasks

  • Add the flag to the four runtime entity types.
  • Decide on orchestra_incident.
  • Kernel coverage asserting the storage does not write these types to the persistent bin.

User interface changes

None.

API changes

None. Entity loads keep their signature and their per-request caching.

Data model changes

None, persistent_cache is a definition flag, not schema.

Issue fork orchestra-3613466

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

mably created an issue. See original summary.

  • mably committed c619b5d4 on 1.x
    fix: #3613466 Runtime entities go through the persistent entity cache,...
mably’s picture

Status: Active » Fixed

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.