Skip to content

[6.x] Scope mutable services#19242

Merged
brandonkelly merged 5 commits into
6.xfrom
feature/scoped-cms-services
Jul 13, 2026
Merged

[6.x] Scope mutable services#19242
brandonkelly merged 5 commits into
6.xfrom
feature/scoped-cms-services

Conversation

@riasvdv

@riasvdv riasvdv commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Description

  • Marks services as Scoped instead of Singleton that hold mutable state
  • Makes sure singletons that call those services don't persist them in the constructor

@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/cpopen Storybook

No changed components detected in this Storybook.

resources/jsopen Storybook

No changed components detected in this Storybook.

Copilot AI left a comment

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.

Pull request overview

This PR addresses lifecycle/state leakage in long-running Craft CMS processes by scoping several mutable services to the current operation/request and avoiding persisting scoped service instances inside singletons (including legacy Yii service wrappers).

Changes:

  • Marked mutable core services (Assets, Gql, RouteTokens, Users, UserPermissions) as #[Scoped] rather than #[Singleton].
  • Updated singleton/legacy call sites to resolve scoped services at call time (rather than storing them from the constructor).
  • Added tests to validate scoped bindings and legacy wrapper behavior, and documented the fix in the changelog.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
yii2-adapter/tests-laravel/Legacy/UserPermissionsLifecycleTest.php Adds a regression test ensuring the legacy Yii service resolves the current scoped core UserPermissions instance.
yii2-adapter/legacy/services/UserPermissions.php Stops caching the core service in the legacy wrapper; resolves it lazily per call to respect scoped lifecycles.
tests/Unit/Support/LifecycleBindingsTest.php Adds a unit test asserting selected services are annotated as #[Scoped].
src/User/Users.php Switches Users service from #[Singleton] to #[Scoped].
src/User/UserPermissions.php Switches UserPermissions service from #[Singleton] to #[Scoped].
src/RouteToken/RouteTokens.php Switches RouteTokens service from #[Singleton] to #[Scoped].
src/Gql/Gql.php Switches Gql service from #[Singleton] to #[Scoped].
src/Asset/Volumes.php Removes persisted Assets dependency from this singleton; resolves Assets via the container when needed.
src/Asset/Assets.php Switches Assets service to #[Scoped] and tightens the temp-folder cache docblock.
CHANGELOG.md Notes the lifecycle leak fix in the Unreleased section.

Comment thread src/Asset/Assets.php Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@riasvdv riasvdv force-pushed the feature/scoped-cms-services branch from 14cd5ec to 29bbe52 Compare July 12, 2026 19:20
@riasvdv riasvdv requested a review from brandonkelly July 12, 2026 19:28
@riasvdv riasvdv marked this pull request as ready for review July 12, 2026 19:28
@brandonkelly brandonkelly merged commit f976e7f into 6.x Jul 13, 2026
@brandonkelly brandonkelly deleted the feature/scoped-cms-services branch July 13, 2026 17:14
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.

3 participants