Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Latest
------

## Changes
* [#371](https://github.com/cleverage/process-bundle/issues/371) `ProcessManager`: executing a process while it is already running, by itself or through its sub-processes (`A → B → A` with `ProcessExecutorTask` (`process_executor`)), is deprecated and will throw an exception in 6.0: the second execution resets the states and task instances of the running process (one configuration per process code), which then returns the output of the deepest execution. The deprecation names the chain of processes; the execution goes on as before. The same sub-process executed several times in a row, or a process executed again by a listener of the process events, is not concerned. Update documentation, add tests.

## Fixes
* [#367](https://github.com/cleverage/process-bundle/issues/367) `ProcessLauncherTask` (`process_launcher`) with `json_buffering`: when the sub-process writes nothing into its JSON buffer (no `end_point`, or an output that is not an array), the task outputs nothing again, as before 5.5, instead of the path of an empty file, and the empty buffer is removed. The buffer of a failed sub-process, and those of the still running sub-processes stopped because of it, are removed too (one file was left in the temporary directory for each launch). Update documentation, add tests.
* [#368](https://github.com/cleverage/process-bundle/issues/368) `YamlWriterTask` (`yaml_writer`): the parent directory is created for a local path only (no scheme, or `file://`), not for a stream wrapper (`compress.zlib://`, `s3://`...), which failed, or `php://stdout`, which created a `php:` directory. Update documentation, add tests.
Expand Down
14 changes: 13 additions & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ Upgrade Guide

## v5.6

Some behaviours change: check the points below.
One deprecation, and some behaviours change: check the points below.

### Recursive process execution

Executing a process while it is already running, by itself or through its sub-processes (`A → B → A` with the
`process_executor` task), is deprecated since 5.6 (`Since cleverage/process-bundle 5.6: Executing the process "A" while
it is already running (A -> B -> A) is deprecated...`) and will throw an exception in 6.0. A process has only one set of
task instances and states: the second execution resets them while the first one is running, which then returns the
output of the deepest execution.

Iterate with an iterable task (e.g. a reader or `constant_iterable_output` followed by `process_executor`) instead of
recursing, or use the `process_launcher` task, which runs the process in a separate PHP process. Executing the same
sub-process several times in a row is not concerned.

### Finalization of the tasks when the process fails

Expand Down
3 changes: 3 additions & 0 deletions docs/04-advanced_workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ values when executing the parent process.
This is a good way to split a big workflow into small, testable processes. Private processes (`public: false`) are
hidden from `cleverage:process:list` (unless `--all` is used) but can still be executed.

Executing a process while it is already running, by itself or through its sub-processes, is deprecated and will throw
an exception in 6.0 (see the [ProcessExecutorTask](reference/tasks/process_executor_task.md#notes)).

## Events

Events are dispatched around process execution (see `CleverAge\ProcessBundle\Event\ProcessEvent`, which gives access
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/tasks/process_executor_task.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ Notes
* The `process` option is checked when the task is initialized: with an unknown process, the initialization fails, the
error is logged and, with process-bundle v5, the parent process fails when the task is first executed (see
[initializable tasks](../../02-task_types.md#initializable-tasks)).
* Executing a process while it is already running, by itself or through its sub-processes (`A → B → A`), is
deprecated since 5.6 and will throw an exception in 6.0: a process has only one set of task instances and states,
which the second execution resets while the first one is running (the running process then returns the output of the
deepest execution). A deprecation naming the chain of processes (`A -> B -> A`) is triggered, and the execution goes
on. Iterate with an iterable task instead of recursing, or use the [ProcessLauncherTask](process_launcher_task.md),
which runs the process in a separate PHP process. Executing the same sub-process several times in a row (e.g. for
each input) is not concerned.
26 changes: 25 additions & 1 deletion src/Manager/ProcessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ class ProcessManager implements ProcessManagerInterface, ResetInterface
*/
protected array $processedBlockings = [];

/**
* Codes of the processes being executed, a sub-process after its parent: a process has only one configuration (task
* instances and states), executing it again while it is running resets them.
*
* @var list<string>
*/
protected array $runningProcessCodes = [];

protected ?ProcessHistory $processHistory = null;

protected ?TaskConfiguration $taskConfiguration = null;
Expand Down Expand Up @@ -107,6 +115,7 @@ public function reset(): void
{
$this->processedIterables = [];
$this->processedBlockings = [];
$this->runningProcessCodes = [];
$this->processHistory = null;
$this->taskConfiguration = null;
}
Expand Down Expand Up @@ -141,7 +150,22 @@ public function execute(string $processCode, mixed $input = null, array $context
);
$this->processLogger->debug('Process start');

$result = $this->doExecute($processCode, $input, $context);
// @deprecated since 5.6, in v6.0 an exception will be thrown
if (\in_array($processCode, $this->runningProcessCodes, true)) {
trigger_deprecation(
'cleverage/process-bundle',
'5.6',
'Executing the process "%s" while it is already running (%s) is deprecated: it resets the states and task instances of the running process. In v6.0, an exception will be thrown.',
$processCode,
implode(' -> ', [...$this->runningProcessCodes, $processCode]),
);
}
$this->runningProcessCodes[] = $processCode;
try {
$result = $this->doExecute($processCode, $input, $context);
} finally {
array_pop($this->runningProcessCodes);
}
// doExecute() leaves the history of the executed process, read before restoring the one of the parent
$processStopped = $this->processHistory?->isStopped() ?? false;
$this->processHistory = $parentProcessHistory;
Expand Down
Loading
Loading