Skip to content

[5.x] _indexes files are incorrect when parallel Stache warming #13265

@hastinbe

Description

@hastinbe

Bug description

When Stache stores are warmed in parallel, entry collection stores fail to include data in their _indexes files. This causes inconsistent index serialization between sequential and parallel warming.

I'm open to ideas on how the _indexes file in parallel warming can match sequential. My attempts so far have been unsuccessful because indexUsage() tracks indexes that have been loaded during runtime, making the _indexes file non-deterministic and dependent on execution order, which differs between sequential and parallel warming.

I'm not sure if we need to revert the parallel warming, but maybe someone who understands how this part of the stache works can chime in if this mismatch is actually problematic or not. I do have a commit prepared to revert the parallel warming while keeping the other improvements from PR #12894

Expected Behavior

Entry collection stores should include all defined indexes (including taxonomy indexes like categories, tags, and standard indexes like site, uri, path) in their _indexes files, regardless of whether stores are warmed sequentially or in parallel. The _indexes files should be identical between both warming methods.

Actual Behavior

When warming in parallel:

  • Entry collection _indexes files are missing some indexes that are present in sequential mode
  • Some collections are missing indexes like site (e.g., entries/pages/_indexes is missing site)
  • Taxonomy indexes may be missing if dependency stores (collections, taxonomies) aren't warmed first
  • The contents of _indexes files are inconsistent and non-deterministic

When warming sequentially:

  • All indexes are correctly included, including taxonomy indexes and standard indexes like site
  • The _indexes files contain all indexes that have been loaded during the warming process

Example Output

Sequential warming:

users/_indexes:                 9999999999a:1:{i:0;s:4:"path";}
asset-containers/_indexes:      9999999999a:1:{i:0;s:4:"path";}
assets/assets/_indexes:         9999999999a:1:{i:0;s:4:"path";}
assets/entries_images/_indexes: 9999999999a:1:{i:0;s:4:"path";}
global-variables/_indexes:      9999999999a:1:{i:0;s:4:"path";}
globals/_indexes:               9999999999a:1:{i:0;s:4:"path";}
nav-trees/_indexes:             9999999999a:1:{i:0;s:4:"path";}
collections/_indexes:           9999999999a:1:{i:0;s:4:"path";}
collection-trees/_indexes:      9999999999a:1:{i:0;s:4:"path";}
navigation/_indexes:            9999999999a:1:{i:0;s:4:"path";}
entries/pages/_indexes:         9999999999a:3:{i:0;s:4:"path";i:1;s:4:"site";i:2;s:3:"uri";}
entries/collection1/_indexes:   9999999999a:1:{i:0;s:4:"path";}
entries/collection2/_indexes:   9999999999a:5:{i:0;s:4:"path";i:1;s:10:"categories";i:2;s:4:"site";i:3;s:3:"uri";}
taxonomies/_indexes:            9999999999a:1:{i:0;s:4:"path";}
terms/categories/_indexes:      9999999999a:2:{i:0;s:12:"associations";i:1;s:4:"path";}

Parallel warming:

users/_indexes:                 9999999999a:1:{i:0;s:4:"path";}
asset-containers/_indexes:      9999999999a:1:{i:0;s:4:"path";}
assets/assets/_indexes:         9999999999a:1:{i:0;s:4:"path";}
assets/entries_images/_indexes: 9999999999a:1:{i:0;s:4:"path";}
global-variables/_indexes:      9999999999a:1:{i:0;s:4:"path";}
globals/_indexes:               9999999999a:1:{i:0;s:4:"path";}
nav-trees/_indexes:             9999999999a:1:{i:0;s:4:"path";}
collections/_indexes:           9999999999a:1:{i:0;s:4:"path";}
collection-trees/_indexes:      9999999999a:1:{i:0;s:4:"path";}
navigation/_indexes:            9999999999a:1:{i:0;s:4:"path";}
entries/pages/_indexes:         9999999999a:2:{i:0;s:3:"uri";i:1;s:4:"site";}
entries/collection1/_indexes:   9999999999a:2:{i:0;s:4:"path";i:1;s:4:"site";}
entries/collection2/_indexes:   9999999999a:2:{i:0;s:3:"uri";i:1;s:4:"site";}
taxonomies/_indexes:            9999999999a:1:{i:0;s:4:"path";}
terms/categories/_indexes:      9999999999a:2:{i:0;s:12:"associations";i:1;s:4:"path";}

How to reproduce

Compare _indexes after warming in sequential and parallel

find storage/framework/cache/data/stache/indexes -name '_indexes' -type f -exec sh -c '
    key="${1#*stache/indexes/}"
    printf "%-40s %s\n" "$key:" "$(cat "$1")"
  ' _ {} \;

Logs

Environment

Laravel Version: 12.38.0
PHP Version: 8.3.6

Installation

Other (please explain)

Additional details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions