Рабочие потоки как конечные автоматы

Компонент рабочего потока моделируется после сети рабочего потока (Workflow net), которая является подклассом of a Petri net. Путём добавления дальнейших ограничений, вы можете получить конечный автомат. Наиболее важным аспектом является то, что конечный автомат не может находиться одновременно более, чем в одном месте. Также стоит отметить, что если рабочий поток обычно не имеет цикличный путь в графике определения, то для конечного автомата это обычное дело.

Пример конечного автомата

Запрос на включение кода начинается в иходном состоянии "старта", состоянии, например, для выполнения тестов в Travis. Когда они закончены, запрос на включение кода находится в состоянии "обзора", когда участники могут запрашивать изменения, отвергать или принимать запрос. В любое время вы также можете "обновить" запрос, что приведёт к ещё одному запуску Travis.

../_images/pull_request.png

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

  • YAML
     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
    # app/config/config.yml
    framework:
        workflows:
            pull_request:
                type: 'state_machine'
                supports:
                    - AppBundle\Entity\PullRequest
                places:
                    - start
                    - coding
                    - travis
                    - review
                    - merged
                    - closed
                transitions:
                    submit:
                        from: start
                        to: travis
                    update:
                        from: [coding, travis, review]
                        to: travis
                    wait_for_review:
                        from: travis
                        to: review
                    request_change:
                        from: review
                        to: coding
                    accept:
                        from: review
                        to: merged
                    reject:
                        from: review
                        to: closed
                    reopen:
                        from: closed
                        to: review
    
  • XML
     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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="utf-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:framework="http://symfony.com/schema/dic/symfony"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
            http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
    >
    
        <framework:config>
            <framework:workflow name="pull_request" type="state_machine">
                <framework:marking-store type="single_state"/>
    
                <framework:support>AppBundle\Entity\PullRequest</framework:support>
    
                <framework:place>start</framework:place>
                <framework:place>coding</framework:place>
                <framework:place>travis</framework:place>
                <framework:place>review</framework:place>
                <framework:place>merged</framework:place>
                <framework:place>closed</framework:place>
    
                <framework:transition name="submit">
                    <framework:from>start</framework:from>
    
                    <framework:to>travis</framework:to>
                </framework:transition>
    
                <framework:transition name="update">
                    <framework:from>coding</framework:from>
                    <framework:from>travis</framework:from>
                    <framework:from>review</framework:from>
    
                    <framework:to>travis</framework:to>
                </framework:transition>
    
                <framework:transition name="wait_for_review">
                    <framework:from>travis</framework:from>
    
                    <framework:to>review</framework:to>
                </framework:transition>
    
                <framework:transition name="request_change">
                    <framework:from>review</framework:from>
    
                    <framework:to>coding</framework:to>
                </framework:transition>
    
                <framework:transition name="accept">
                    <framework:from>review</framework:from>
    
                    <framework:to>merged</framework:to>
                </framework:transition>
    
                <framework:transition name="reject">
                    <framework:from>review</framework:from>
    
                    <framework:to>closed</framework:to>
                </framework:transition>
    
                <framework:transition name="reopen">
                    <framework:from>closed</framework:from>
    
                    <framework:to>review</framework:to>
                </framework:transition>
    
            </framework:workflow>
    
        </framework:config>
    </container>
    
  • 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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    // app/config/config.php
    
    $container->loadFromExtension('framework', array(
        // ...
        'workflows' => array(
            'pull_request' => array(
              'type' => 'state_machine',
              'supports' => array('AppBundle\Entity\PullRequest'),
              'places' => array(
                'start',
                'coding',
                'travis',
                'review',
                'merged',
                'closed',
              ),
              'transitions' => array(
                'start'=> array(
                  'from' => 'start',
                  'to' => 'travis',
                ),
                'update'=> array(
                  'from' => array('coding','travis','review'),
                  'to' => 'travis',
                ),
                'wait_for_reivew'=> array(
                  'from' => 'travis',
                  'to' => 'review',
                ),
                'request_change'=> array(
                  'from' => 'review',
                  'to' => 'coding',
                ),
                'accept'=> array(
                  'from' => 'review',
                  'to' => 'merged',
                ),
                'reject'=> array(
                  'from' => 'review',
                  'to' => 'closed',
                ),
                'reopen'=> array(
                  'from' => 'start',
                  'to' => 'review',
                ),
              ),
            ),
        ),
    ));
    

Теперь вы можетеиспользовать этот конечный автомат, получая сервис state_machine.pull_request service:

1
$stateMachine = $this->container->get('state_machine.pull_request');

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.