Skip to content

#266 - Allow to stop a running process with stop checkers - #267

Merged
njoubert-cleverage merged 1 commit into
mainfrom
266
Oct 13, 2026
Merged

njoubert-cleverage merged 1 commit into
mainfrom
266

Conversation

@njoubert-cleverage

Copy link
Copy Markdown
Member

Description

Fixes #266: a running process can be stopped from the outside (first step of cleverage/ui-process-bundle#143, the "Stop" action of the UI).

Changes

  • New CleverAge\ProcessBundle\Model\ProcessStopCheckerInterface (shouldStop(ProcessState $state): bool). Implementations are autoconfigured (tag cleverage_process.stop_checker) and injected into ProcessManager (new optional iterable $stopCheckers = [] argument, !tagged_iterator in manager.yaml).
  • ProcessManager::processExecution() asks the checkers before each task execution (process, proceed, flush; once per item for the iterable tasks). When one of them returns true, the task is not executed and its state is stopped with the new CleverAge\ProcessBundle\Exception\ProcessStoppedException: the process fails as with the stop error strategy, whatever the task error_strategy (a skip strategy or error outputs do not swallow the stop). It throws a ProcessFailedException whose previous exception is the ProcessStoppedException, and cleverage_process.fail is dispatched.
  • A service rather than an event: the hook is called once per item, and a dispatch per item (traced in dev) would be costly. Without checker, the overhead is a loop over an empty list.
  • Throttling is the responsibility of the checkers (documented with an example).

Note (differs from the issue description): as for any failure (task error with the stop strategy), the remaining items are not flushed and the tasks are not finalized: doExecute() leaves on the exception. Kept consistent on purpose; running flush / finalize on failure would be a broader change.

Documentation

  • docs/04-advanced_workflow.md: new "Stopping a running process" section (behaviour, throttled checker example, limits: long blocking calls, ProcessLauncherTask / ProcessExecutorTask sub-processes, recognizing a stop in the chain of previous exceptions).
  • CHANGELOG (Latest).

Tests

  • ProcessManagerStopCheckerTest (real ProcessManager, ConstantIterableOutputTask + recording task): without checker all items run; a checker returning false is called before each task / item; a stop on the 3rd item processes only 1 and 2, ignores the skip strategy and the error output, ProcessFailedException with the ProcessStoppedException as previous, failed event and history; any checker can request the stop.
  • CleverAgeProcessExtensionTest: autoconfiguration tag and tagged iterator argument of the process manager.
  • 903 tests OK. PHPStan, PHP-CS-Fixer, Rector OK.

Requirements

  • Documentation updates
    • Reference
    • Cookbooks
    • Changelog
  • Unit tests

Breaking changes

None: new interface, new exception, new optional constructor argument; no behaviour change without checker. Minor.

🤖 Generated with Claude Code

Services implementing the new ProcessStopCheckerInterface (autoconfigured, tag
cleverage_process.stop_checker, new optional $stopCheckers argument of
ProcessManager) are asked before each task execution; when one of them returns
true, the task is not executed and the process fails with a
ProcessFailedException whose previous exception is the new
ProcessStoppedException.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@njoubert-cleverage
njoubert-cleverage merged commit 36c3a84 into main Oct 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow to stop a running process (cooperative stop hook between task executions)

1 participant