github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/v2/design/framework/flow.md (about)

     1  # Flow
     2  
     3  Flow is the concept of a workflow. A way to orchestrate multiple actions in a single place.
     4  
     5  ## Overview
     6  
     7  Flow is a form of workflow orchestration. It acts as a state machine which manages a specific set of steps or actions while dealing with the fault tolerance aspects. 
     8  This can include processing a request, publishing an event, storing data and waiting for some prior action. Normally we codify all this by hand including the 
     9  error handling. Flows would essentially manage the majority of this for us.
    10  
    11  ## Design
    12  
    13  Flow service must provide Flow manager that able to maipulate flows and steps inside it. And also Executor that runs workload in flow order. Most essential part, that we must provide not only static flow definition, but also provide ability to register some endpoint in flow after all services starts. So each service does not need to know about others.
    14  
    15  ## Implemenations
    16  
    17  Now we have only one default flow implementation. It uses worker pool to distribute workload across workers. And some predefined operations, like:
    18  
    19  * ClientCallOperation - calls service endpoint via micro client (rpc)
    20  
    21  * ClientPublishOperation - call service endpoint via broker (pubsub)
    22  
    23  * FlowExecuteOperation - call the same or another flow with specific step, 
    24    useful to able to rollback some failed action. FlowExecuteOperation utlize
    25    previous two operations to call endpoints
    26  
    27  ## Design
    28  
    29  Flow interface modifies flow
    30  
    31  ```go
    32  type Flow interface {
    33    // Init flow with options
    34    Init(...Option) error
    35    // Get flow options
    36    Options() Options
    37    // Create step in specific flow
    38    CreateStep(flow string, step *Step) error
    39    // Delete step from specific flow
    40    DeleteStep(flow string, step *Step) error
    41    // Replace step in specific flow
    42    ReplaceStep(flow string, oldstep *Step, newstep *Step) error
    43    // Lookup specific flow
    44    Lookup(flow string) ([]*Step, error)
    45    // Execute specific floa via Executor and returns request id and error, optionally fills rsp in case of sync execution
    46    Execute(steps []*Step, req interface{}, rsp interface{}, opts ...ExecuteOption) (string, error)
    47  }                                                                                                
    48  ```
    49  
    50  Flow options
    51  ```go
    52  type Options struct {
    53    // Executor used to execute steps in flow
    54    Executor Executor
    55    // Context is used for storing non default options
    56    Context context.Context
    57  }
    58  ```
    59  
    60  Executor interface provides steps execution 
    61  
    62  ```go
    63  type Executor interface {
    64    // Init flow with options
    65    Init(...ExecutorOption) error
    66    // Get flow options
    67    Options() ExecutorOptions
    68  	// Run execution with sync/async capability
    69  	Execute(steps []*Step, req interface{}, rsp interface{}, opts ...ExecuteOption) (string, error)
    70  	// Resume specific flow execution by id
    71  	Resume(flow string, id string) error
    72  	// Pause specific flow execution by id
    73  	Pause(flow string, id string) error
    74  	// Abort specific flow execution by id
    75  	Abort(flow string, id string) error
    76  	// Status show status specific flow execution by request id
    77  	Status(flow string, id string) (Status, error)
    78  	// Result get result of the flow step
    79  	Result(flow string, id string, step string) ([]byte, error)
    80  	// Stop executor and drain active workers
    81  	Stop() error
    82  }
    83  ```
    84  
    85  Executor options
    86  
    87  ```go
    88  type ExecutorOptions struct {
    89    // Flow is used to be able to run another flow from current execution
    90    Flow Flow                                           
    91    // ErrorHandler is used for recovery panics
    92    ErrorHandler func(interface{})
    93    // Context is used for storing non default options
    94    Context context.Context
    95  }
    96  ```
    97  
    98  Step definition
    99  
   100  ```go
   101  type Step struct {
   102    // name of step
   103    ID string
   104    // Retry count for step
   105    Retry int
   106    // Timeout for step
   107    Timeout int
   108    // Step operation to execute
   109    Operation Operation
   110    // Which step use as input
   111    Input string
   112    // Where to place output
   113    Output string
   114    // Steps IDs that runs after this step
   115    After []*Step
   116    // Steps IDs that runs before this step
   117    Before []*Step
   118    // Step operation to execute in case of error
   119    Fallback Operation
   120  }                                                                                  
   121  ```
   122  
   123  Operation definition
   124  
   125  ```go
   126  type Operation interface {
   127    Name() string
   128    String() string
   129    Type() string
   130    New() Operation
   131    Decode(*pb.Operation)
   132    Encode() *pb.Operation
   133    Execute(context.Context, []byte, ...ExecuteOption) ([]byte, error)
   134    Options() OperationOptions
   135  }
   136  ```
   137  
   138  Execute options
   139  
   140  ```go
   141  type ExecuteOptions struct {
   142    // Passed flow name
   143    Flow string
   144    // Passed execution id                                                      
   145    ID strinh
   146    // Passed step to start from
   147    Step string
   148    // Step ID to store Output data
   149    Output string
   150    // Timeout for currenct execution
   151    Timeout time.Duration
   152    // Async execution run, dont wait for complete
   153    Async bool
   154    // Concurrency specify count of workers create for steps in flow
   155    Concurrency int
   156    // Retries specify count of retries for each step in execution
   157    Retries int
   158    // Client for communication
   159    Client client.Client
   160    // Context is used for storing non default options
   161    Context context.Context
   162  }
   163  ```
   164  
   165  Operation options
   166  
   167  ```go
   168  type OperationOptions struct {
   169    Timeout   time.Duration
   170    Retries   int
   171    AllowFail bool
   172    Context   context.Context
   173  }
   174  ```
   175  
   176  Step statuses
   177  
   178  ```go
   179  
   180  type Status int
   181  
   182  const (                       
   183    StatusUnknown Status = iota
   184    StatusPending
   185    StatusFailure
   186    StatusSuccess
   187    StatusPaused
   188    StatusAborted
   189    StatusStopped
   190  )                             
   191  
   192  ```
   193  
   194  ## Status
   195  
   196  Incomplete. Lacks of timeout, retries. Don't have proper supports to pause/resume/stop/restart flow execution.
   197  But its easy to add after minimal working code has been merged.
   198  
   199