-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.go
More file actions
99 lines (91 loc) · 2.5 KB
/
action.go
File metadata and controls
99 lines (91 loc) · 2.5 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package agent
import (
"net/http"
"github.com/mistifyio/mistify-agent/config"
"github.com/pborman/uuid"
)
type (
// Stage is a single step an action must take
Stage struct {
Service *Service
Type config.ActionType
Method string
Args map[string]string
Request interface{}
Response interface{}
RW http.ResponseWriter // For streaming responses
}
// Pipeline is a full set of stage instances required to complete an action
Pipeline struct {
ID string
Action string
Type config.ActionType
Stages []*Stage
PreStageFunc func(*Pipeline, *Stage) error
PostStageFunc func(*Pipeline, *Stage) error
DoneChan chan error // Signal async is done or errored, for post-hooks
}
// Action is a full set of stage templates required to complete an action
Action struct {
Name string
Type config.ActionType
Stages []*Stage
}
)
// Run makes an individual stage request
func (stage *Stage) Run() error {
if stage.Type == config.StreamAction {
stage.Service.Client.DoRaw(stage.Request, stage.RW)
return nil
}
return stage.Service.Client.Do(stage.Method, stage.Request, stage.Response)
}
// Run executes each stage in the pipeline. It bails out as soon as an error
// is encountered
func (pipeline *Pipeline) Run() error {
var err error
for _, stage := range pipeline.Stages {
if pipeline.PreStageFunc != nil {
if err = pipeline.PreStageFunc(pipeline, stage); err != nil {
break
}
}
if err = stage.Run(); err != nil {
break
}
if pipeline.PostStageFunc != nil {
if err = pipeline.PostStageFunc(pipeline, stage); err != nil {
break
}
}
}
if pipeline.DoneChan != nil {
pipeline.DoneChan <- err
}
return err
}
// GeneratePipeline creates an instance of Pipeline based on an action's
// stages and supplied request & response. It is returned so that any additional
// modifications (such as adding stage args to requests) can be made before
// running if needed.
func (action *Action) GeneratePipeline(request interface{}, response interface{}, rw http.ResponseWriter, done chan error) *Pipeline {
pipeline := &Pipeline{
ID: uuid.New(),
Action: action.Name,
Type: action.Type,
Stages: make([]*Stage, len(action.Stages)),
DoneChan: done,
}
for i, stage := range action.Stages {
pipeline.Stages[i] = &Stage{
Service: stage.Service,
Type: action.Type,
Method: stage.Method,
Args: stage.Args,
Request: request,
Response: response,
RW: rw,
}
}
return pipeline
}