Робочі процеси та машини станів

Дата оновлення перекладу 2022-12-23

Робочі процеси та машини станів

Робочі процеси

Робочий процес - це модель процесу у вашому додатку. Це може бути процес того, як пост блогу проходить етапи від чернетки, до рецензії, до публікації. Інший приклад - коли користувач відправляє декілька різних форм для виконання задачі. Такі процеси краще всього тримати подалі від ваших моделей, і варто визначати у конфігурації.

Визначення робочего процесу складається з місць та дій, які потрібно перемістити з одного місця в інше. Ці дії називаються переходами. Робочий процес також має знати місце розташування кожного обʼєкта у робочому процесі. Сховище маркування записує поточне місце у властивіть обʼєкта.

Note

Термінологія вище часто використовується при обговоренні робочих процесів та мереж Петрі

Приклади

Найпростіший робочий процес виглядає так. Він містить два місця і один перехід.

Робочі процеси можуть бути складнішими, коли вони описують реальний бізнес-приклад. Робочий процес нижче описує процес заповнення заявки на роботу.

Коли ви заповнюєте заявку на роботу у цьому прикладі, у вас буде від 4 до 7 коків, в залежності від того, на яку роботу ви подаєтеся. Деякі види роботи вимагають тестів особистості, тестів на логіку та/або формальних вимог, на які повинен відповісти користувач. Деякі - не вимагають цього. GuardEvent використовується для того, щоб визначити, які наступні кроки дозволені для конкретної заявки.

При визначенні робочого процесу таким чином, існує огляд того, як виглядає процес. Логіка процесу не змішується з контролерами, моделями або переглядом. Порядок кроків може бути змінений лише шляхом зміни конфігурації.

Машини станів

Машини станів - це підмножина робочого процесу, ціллю якої є утримання станів вашої моделі. Найважливіші відмінності між ними:

  • Робочі процеси можуть бути більше, ніж в одному місці, водночас, а машини станів - ні;
  • Для того, щоб застосувати перехід, робочі процеси вимагають того, щоб обʼєкт був у всіх попередніх місцях переходу, в той час як машини станів вимагають лише щоб обʼєкт був хоча би в одному з цих місць.

Приклад

Запит на включення запускає початковий "стартовий" стан, а потім стан "тестування" для, наприклад, виконання тестів у безперервному стеку інтеграції. Коли воно буде закінчено, запит на включення переходить у стан "рецензії", де можна зробити запит на зміни, прийняти або відхилити запит на включення. У будь який час, ви також можете "оновити" запит на включення, що призведе до нового запуску безперервної інтеграції.

Нижче можна побачити конфігурацію запиту на включення машини станів.

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# config/packages/workflow.yaml
framework:
    workflows:
        pull_request:
            type: 'state_machine'
            marking_store:
                 type: 'method'
                 property: 'currentPlace'
            supports:
                - App\Entity\PullRequest
            initial_marking: start
            places:
                - start
                - coding
                - test
                - review
                - merged
                - closed
            transitions:
                submit:
                    from: start
                    to: test
                update:
                    from: [coding, test, review]
                    to: test
                wait_for_review:
                    from: test
                    to: review
                request_change:
                    from: review
                    to: coding
                accept:
                    from: review
                    to: merged
                reject:
                    from: review
                    to: closed
                reopen:
                    from: closed
                    to: review

У додатках Symfony, використовуючи конфігурацію services.yaml за замовчуванням , ви можете отримати цю машину станів, впровадивши сервіс реєстру Робочого процесу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ...
use App\Entity\PullRequest;
use Symfony\Component\Workflow\Registry;

class SomeService
{
    private $workflows;

    public function __construct(Registry $workflows)
    {
        $this->workflows = $workflows;
    }

    public function someMethod(PullRequest $pullRequest)
    {
        $stateMachine = $this->workflows->get($pullRequest, 'pull_request');
        $stateMachine->apply($pullRequest, 'wait_for_review');
        // ...
    }

    // ...
}

Symfony автоматично створює сервіс для кожного робочого процесу (Workflow) або машини станів (StateMachine), які ви визначили у своїй конфігурації. Це означає, що ви можете використати workflow.pull_request або state_machine.pull_request, відповідно, у ваших визначеннях сервісу, щоб отримати доступ до правильного сервісу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ...
use App\Entity\PullRequest;
use Symfony\Component\Workflow\StateMachine;

class SomeService
{
    private $stateMachine;

    public function __construct(StateMachine $stateMachine)
    {
        $this->stateMachine = $stateMachine;
    }

    public function someMethod(PullRequest $pullRequest)
    {
        $this->stateMachine->apply($pullRequest, 'wait_for_review', [
            'log_comment' => 'My logging comment for the wait for review transition.',
        ]);
        // ...
    }

    // ...
}

Автоматична та ручна валідація

Під час розігріву кешу, Symfony валідує робочі процеси та машини станів, які визначені у файлах конфігурації. Якщо ваші робочі процеси або машини станів визначені програмно, а не у файлі конфігурації, ви можете валідувати їх за допомогою WorkflowValidator і StateMachineValidator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ...
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\StateMachine;
use Symfony\Component\Workflow\Validator\StateMachineValidator;

$states = ['created', 'activated', 'deleted'];
$stateTransitions = [
    new Transition('activate', 'created', 'activated'),
    // Ця дубльована подія "from" стану "created" не валідна
    new Transition('activate', 'created', 'deleted'),
    new Transition('delete', 'activated', 'deleted'),
];

// При запуску валідація не проводиться
$definition = new Definition($states, $stateTransitions);

$validator = new StateMachineValidator();
// Викликає InvalidDefinitionException у випадку невалідного визначення
$validator->validate($definition, 'My First StateMachine');