@platforma-sdk/workflow-tengo 2.9.5 → 2.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tengo/lib/assets.lib.tengo +52 -52
- package/dist/tengo/lib/assets.swinfo.lib.tengo +45 -45
- package/dist/tengo/lib/constants.lib.tengo +32 -32
- package/dist/tengo/lib/exec.R.internal.lib.tengo +29 -29
- package/dist/tengo/lib/exec.R.lib.tengo +166 -166
- package/dist/tengo/lib/exec.constants.lib.tengo +4 -4
- package/dist/tengo/lib/exec.descriptor.lib.tengo +31 -31
- package/dist/tengo/lib/exec.internal.lib.tengo +297 -297
- package/dist/tengo/lib/exec.lib.tengo +815 -815
- package/dist/tengo/lib/exec.monetization.lib.tengo +130 -130
- package/dist/tengo/lib/exec.package.lib.tengo +212 -212
- package/dist/tengo/lib/exec.python.internal.lib.tengo +6 -6
- package/dist/tengo/lib/exec.python.lib.tengo +146 -146
- package/dist/tengo/lib/exec.runcmd.lib.tengo +371 -371
- package/dist/tengo/lib/exec.runenv.lib.tengo +92 -92
- package/dist/tengo/lib/exec.stream.lib.tengo +40 -40
- package/dist/tengo/lib/file.internal.lib.tengo +77 -77
- package/dist/tengo/lib/file.lib.tengo +57 -57
- package/dist/tengo/lib/ll.lib.tengo +244 -244
- package/dist/tengo/lib/maps.lib.tengo +152 -152
- package/dist/tengo/lib/objects.lib.tengo +13 -13
- package/dist/tengo/lib/oop.lib.tengo +19 -19
- package/dist/tengo/lib/path.lib.tengo +125 -125
- package/dist/tengo/lib/pframes.constants.lib.tengo +28 -28
- package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +33 -33
- package/dist/tengo/lib/pframes.lib.tengo +43 -43
- package/dist/tengo/lib/pframes.ll.lib.tengo +72 -72
- package/dist/tengo/lib/pframes.pcolumn.lib.tengo +49 -49
- package/dist/tengo/lib/pframes.spec.lib.tengo +96 -96
- package/dist/tengo/lib/pframes.util.lib.tengo +288 -288
- package/dist/tengo/lib/pframes.xsv.lib.tengo +272 -272
- package/dist/tengo/lib/render.lib.tengo +75 -75
- package/dist/tengo/lib/sets.lib.tengo +68 -68
- package/dist/tengo/lib/slices.lib.tengo +258 -155
- package/dist/tengo/lib/smart.lib.tengo +1069 -1069
- package/dist/tengo/lib/test.lib.tengo +161 -161
- package/dist/tengo/lib/tpl.lib.tengo +515 -515
- package/dist/tengo/lib/tpl.state-await.lib.tengo +240 -240
- package/dist/tengo/lib/tpl.util.lib.tengo +9 -9
- package/dist/tengo/lib/validation.lib.tengo +378 -378
- package/dist/tengo/lib/workdir.lib.tengo +331 -331
- package/dist/tengo/lib/workdir.proc.lib.tengo +144 -144
- package/dist/tengo/lib/workdir.save.lib.tengo +130 -130
- package/dist/tengo/lib/workflow.bobject.lib.tengo +26 -26
- package/dist/tengo/lib/workflow.bquery.lib.tengo +165 -165
- package/dist/tengo/lib/workflow.constants.lib.tengo +2 -2
- package/dist/tengo/lib/workflow.context.lib.tengo +32 -32
- package/dist/tengo/lib/workflow.lib.tengo +206 -206
- package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
- package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
- package/package.json +2 -2
|
@@ -1,254 +1,254 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Library implementing state machine to await certain resource states in
|
|
3
|
+
* ephemeral templates.
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
tx := import("tx")
|
|
7
7
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
8
8
|
text := import("text")
|
|
9
9
|
|
|
10
10
|
createContext := func() {
|
|
11
|
-
return {
|
|
12
|
-
activeSubscriptions: {},
|
|
13
|
-
resolvedStates: {}
|
|
14
|
-
}
|
|
11
|
+
return {
|
|
12
|
+
activeSubscriptions: {},
|
|
13
|
+
resolvedStates: {}
|
|
14
|
+
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
awaitOneState := func(field, path, state) {
|
|
18
|
-
if field.isErrorSet() && !field.isValueSet() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return { type: "Ready" }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if len(path) > 0 {
|
|
27
|
-
step := path[0]
|
|
28
|
-
rPath := path[1:]
|
|
29
|
-
|
|
30
|
-
if !field.isValueSet() {
|
|
31
|
-
return {
|
|
32
|
-
type: "Subscribe",
|
|
33
|
-
subscriptions: [{
|
|
34
|
-
resource: field.id.ResourceID,
|
|
35
|
-
event: "InputSet"
|
|
36
|
-
}]
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
resource := field.getValue()
|
|
41
|
-
|
|
42
|
-
if is_string(step) {
|
|
43
|
-
nextField := resource.inputs()[step]
|
|
44
|
-
if nextField == undefined {
|
|
45
|
-
if resource.info().InputsLocked {
|
|
46
|
-
ll.panic("field %v not found and inputs locked", step)
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
type: "Subscribe",
|
|
50
|
-
subscriptions: [{
|
|
51
|
-
resource: resource.id,
|
|
52
|
-
event: "FieldCreated"
|
|
53
|
-
},{
|
|
54
|
-
resource: resource.id,
|
|
55
|
-
event: "InputsLocked"
|
|
56
|
-
}]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return awaitOneState(nextField, rPath, state)
|
|
60
|
-
} else if is_map(step) {
|
|
61
|
-
if is_undefined(step.wildcard) == is_undefined(step.match) {
|
|
62
|
-
ll.panic("Unknown step structure: %v", step)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
matcher := undefined
|
|
66
|
-
|
|
67
|
-
if !is_undefined(step.wildcard) {
|
|
68
|
-
if step.wildcard != "*" {
|
|
69
|
-
ll.panic("Complex wildcards are not supported, use { match: \"{regexp}\" }: %v", step.wildcard)
|
|
70
|
-
}
|
|
71
|
-
matcher = func(field) {
|
|
72
|
-
return true
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
regex := text.re_compile(step.match)
|
|
76
|
-
if is_error(regex) {
|
|
77
|
-
ll.panic("Error parsing regex %v: %v", step.match, regex)
|
|
78
|
-
}
|
|
79
|
-
matcher = func(field) {
|
|
80
|
-
return regex.match(field)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if !resource.info().InputsLocked {
|
|
85
|
-
return {
|
|
86
|
-
type: "Subscribe",
|
|
87
|
-
subscriptions: [{
|
|
88
|
-
resource: resource.id,
|
|
89
|
-
event: "InputsLocked"
|
|
90
|
-
}]
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
subscriptions := []
|
|
95
|
-
for nextFieldName, nextField in resource.inputs() {
|
|
96
|
-
if !matcher(nextFieldName) {
|
|
97
|
-
continue
|
|
98
|
-
}
|
|
99
|
-
res := awaitOneState(nextField, rPath, state)
|
|
100
|
-
if res.type == "Ready" {
|
|
101
|
-
continue
|
|
102
|
-
} else if res.type == "Subscribe" {
|
|
103
|
-
subscriptions = append(subscriptions, res.subscriptions...)
|
|
104
|
-
} else {
|
|
105
|
-
ll.panic("Unknown result type: %v", res.type)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if len(subscriptions) == 0 {
|
|
109
|
-
return { type: "Ready" }
|
|
110
|
-
} else {
|
|
111
|
-
return {
|
|
112
|
-
type: "Subscribe",
|
|
113
|
-
subscriptions: subscriptions
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
ll.panic("Malformed state await request path: %v", step)
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
if state == "Exists" {
|
|
121
|
-
return { type: "Ready" }
|
|
122
|
-
} else {
|
|
123
|
-
if !field.isSet() {
|
|
124
|
-
return {
|
|
125
|
-
type: "Subscribe",
|
|
126
|
-
subscriptions: [{
|
|
127
|
-
resource: field.id.ResourceID,
|
|
128
|
-
event: "InputSet"
|
|
129
|
-
}]
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
resource := field.getValue()
|
|
133
|
-
if state == "Set" {
|
|
134
|
-
return { type: "Ready" }
|
|
135
|
-
} else if state == "InputsLocked" {
|
|
136
|
-
if resource.info().InputsLocked {
|
|
137
|
-
return { type: "Ready" }
|
|
138
|
-
} else {
|
|
139
|
-
return {
|
|
140
|
-
type: "Subscribe",
|
|
141
|
-
subscriptions: [{
|
|
142
|
-
resource: resource.id,
|
|
143
|
-
event: "InputsLocked"
|
|
144
|
-
}]
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
} else if state == "AllInputsSet" {
|
|
148
|
-
if resource.info().AllInputsSet {
|
|
149
|
-
return { type: "Ready" }
|
|
150
|
-
} else {
|
|
151
|
-
return {
|
|
152
|
-
type: "Subscribe",
|
|
153
|
-
subscriptions: [{
|
|
154
|
-
resource: resource.id,
|
|
155
|
-
event: "AllInputsSet"
|
|
156
|
-
}]
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
} else if state == "ResourceReady" {
|
|
160
|
-
if resource.info().ResourceReady {
|
|
161
|
-
return { type: "Ready" }
|
|
162
|
-
} else {
|
|
163
|
-
return {
|
|
164
|
-
type: "Subscribe",
|
|
165
|
-
subscriptions: [{
|
|
166
|
-
resource: resource.id,
|
|
167
|
-
event: "ResourceReady"
|
|
168
|
-
}]
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
ll.panic("Unknown await state: %v", state)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
18
|
+
if field.isErrorSet() && !field.isValueSet() {
|
|
19
|
+
// Field is in pure error state (just error and no referenced resource).
|
|
20
|
+
// This is a terminal state, so we stop any traversal here, and return value
|
|
21
|
+
// the same as we would return if we achieved the desired state. It is
|
|
22
|
+
// template's body responsibility to correctly handle the error state.
|
|
23
|
+
return { type: "Ready" }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if len(path) > 0 {
|
|
27
|
+
step := path[0]
|
|
28
|
+
rPath := path[1:]
|
|
29
|
+
|
|
30
|
+
if !field.isValueSet() {
|
|
31
|
+
return {
|
|
32
|
+
type: "Subscribe",
|
|
33
|
+
subscriptions: [{
|
|
34
|
+
resource: field.id.ResourceID,
|
|
35
|
+
event: "InputSet"
|
|
36
|
+
}]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
resource := field.getValue()
|
|
41
|
+
|
|
42
|
+
if is_string(step) {
|
|
43
|
+
nextField := resource.inputs()[step]
|
|
44
|
+
if nextField == undefined {
|
|
45
|
+
if resource.info().InputsLocked {
|
|
46
|
+
ll.panic("field %v not found and inputs locked", step)
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
type: "Subscribe",
|
|
50
|
+
subscriptions: [{
|
|
51
|
+
resource: resource.id,
|
|
52
|
+
event: "FieldCreated"
|
|
53
|
+
},{
|
|
54
|
+
resource: resource.id,
|
|
55
|
+
event: "InputsLocked"
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return awaitOneState(nextField, rPath, state)
|
|
60
|
+
} else if is_map(step) {
|
|
61
|
+
if is_undefined(step.wildcard) == is_undefined(step.match) {
|
|
62
|
+
ll.panic("Unknown step structure: %v", step)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
matcher := undefined
|
|
66
|
+
|
|
67
|
+
if !is_undefined(step.wildcard) {
|
|
68
|
+
if step.wildcard != "*" {
|
|
69
|
+
ll.panic("Complex wildcards are not supported, use { match: \"{regexp}\" }: %v", step.wildcard)
|
|
70
|
+
}
|
|
71
|
+
matcher = func(field) {
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
regex := text.re_compile(step.match)
|
|
76
|
+
if is_error(regex) {
|
|
77
|
+
ll.panic("Error parsing regex %v: %v", step.match, regex)
|
|
78
|
+
}
|
|
79
|
+
matcher = func(field) {
|
|
80
|
+
return regex.match(field)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if !resource.info().InputsLocked {
|
|
85
|
+
return {
|
|
86
|
+
type: "Subscribe",
|
|
87
|
+
subscriptions: [{
|
|
88
|
+
resource: resource.id,
|
|
89
|
+
event: "InputsLocked"
|
|
90
|
+
}]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
subscriptions := []
|
|
95
|
+
for nextFieldName, nextField in resource.inputs() {
|
|
96
|
+
if !matcher(nextFieldName) {
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
res := awaitOneState(nextField, rPath, state)
|
|
100
|
+
if res.type == "Ready" {
|
|
101
|
+
continue
|
|
102
|
+
} else if res.type == "Subscribe" {
|
|
103
|
+
subscriptions = append(subscriptions, res.subscriptions...)
|
|
104
|
+
} else {
|
|
105
|
+
ll.panic("Unknown result type: %v", res.type)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if len(subscriptions) == 0 {
|
|
109
|
+
return { type: "Ready" }
|
|
110
|
+
} else {
|
|
111
|
+
return {
|
|
112
|
+
type: "Subscribe",
|
|
113
|
+
subscriptions: subscriptions
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
ll.panic("Malformed state await request path: %v", step)
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
if state == "Exists" {
|
|
121
|
+
return { type: "Ready" }
|
|
122
|
+
} else {
|
|
123
|
+
if !field.isSet() {
|
|
124
|
+
return {
|
|
125
|
+
type: "Subscribe",
|
|
126
|
+
subscriptions: [{
|
|
127
|
+
resource: field.id.ResourceID,
|
|
128
|
+
event: "InputSet"
|
|
129
|
+
}]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
resource := field.getValue()
|
|
133
|
+
if state == "Set" {
|
|
134
|
+
return { type: "Ready" }
|
|
135
|
+
} else if state == "InputsLocked" {
|
|
136
|
+
if resource.info().InputsLocked {
|
|
137
|
+
return { type: "Ready" }
|
|
138
|
+
} else {
|
|
139
|
+
return {
|
|
140
|
+
type: "Subscribe",
|
|
141
|
+
subscriptions: [{
|
|
142
|
+
resource: resource.id,
|
|
143
|
+
event: "InputsLocked"
|
|
144
|
+
}]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} else if state == "AllInputsSet" {
|
|
148
|
+
if resource.info().AllInputsSet {
|
|
149
|
+
return { type: "Ready" }
|
|
150
|
+
} else {
|
|
151
|
+
return {
|
|
152
|
+
type: "Subscribe",
|
|
153
|
+
subscriptions: [{
|
|
154
|
+
resource: resource.id,
|
|
155
|
+
event: "AllInputsSet"
|
|
156
|
+
}]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} else if state == "ResourceReady" {
|
|
160
|
+
if resource.info().ResourceReady {
|
|
161
|
+
return { type: "Ready" }
|
|
162
|
+
} else {
|
|
163
|
+
return {
|
|
164
|
+
type: "Subscribe",
|
|
165
|
+
subscriptions: [{
|
|
166
|
+
resource: resource.id,
|
|
167
|
+
event: "ResourceReady"
|
|
168
|
+
}]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
ll.panic("Unknown await state: %v", state)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Returns true if all requested states are reached */
|
|
179
179
|
await := func(rootField, ctxStorageResource, requests) {
|
|
180
|
-
pssKey := "await:" + string(rootField.id.ResourceID) + ":" + rootField.id.Name
|
|
181
|
-
prevSubscriptions := ctxStorageResource.kvGetAsJson(pssKey)
|
|
182
|
-
|
|
183
|
-
if !is_undefined(prevSubscriptions) && len(prevSubscriptions) == 0 {
|
|
184
|
-
|
|
185
|
-
ll.panic("Unexpected state, desired state was reached in the previous call")
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if is_undefined(prevSubscriptions) {
|
|
189
|
-
|
|
190
|
-
prevSubscriptions = {}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
subscriptions := {}
|
|
194
|
-
|
|
195
|
-
addSubscription := func(subscription) {
|
|
196
|
-
key := string(subscription.resource) + ":" + subscription.event
|
|
197
|
-
if !is_undefined(subscriptions[key]) {
|
|
198
|
-
return false
|
|
199
|
-
} else {
|
|
200
|
-
subscriptions[key] = subscription
|
|
201
|
-
return true
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
for _, request in requests {
|
|
206
|
-
if !is_map(request) || !is_array(request.path) || !is_string(request.state) {
|
|
207
|
-
ll.panic("Malformed state await request: %v", request)
|
|
208
|
-
}
|
|
209
|
-
res := awaitOneState(rootField, request.path, request.state)
|
|
210
|
-
if res.type == "Ready" {
|
|
211
|
-
continue
|
|
212
|
-
} else if res.type == "Subscribe" {
|
|
213
|
-
for subscription in res.subscriptions {
|
|
214
|
-
addSubscription(subscription)
|
|
215
|
-
}
|
|
216
|
-
} else {
|
|
217
|
-
ll.panic("Unknown result type %v", res.type)
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
for key, sub in subscriptions {
|
|
223
|
-
if !is_undefined(prevSubscriptions[key]) {
|
|
224
|
-
|
|
225
|
-
continue
|
|
226
|
-
}
|
|
227
|
-
e := {}
|
|
228
|
-
e[sub.event] = true
|
|
229
|
-
tx.subscribeTo(sub.resource, pssKey + ":" + key, e)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
for key, _ in prevSubscriptions {
|
|
234
|
-
if !is_undefined(subscriptions[key]) {
|
|
235
|
-
|
|
236
|
-
continue
|
|
237
|
-
}
|
|
238
|
-
tx.unsubscribeFrom(pssKey + ":" + key)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
newPrevSubscriptions := {}
|
|
243
|
-
for key, _ in subscriptions {
|
|
244
|
-
newPrevSubscriptions[key] = true
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
ctxStorageResource.kvSetJson(pssKey, newPrevSubscriptions)
|
|
248
|
-
|
|
249
|
-
return len(subscriptions) == 0
|
|
180
|
+
pssKey := "await:" + string(rootField.id.ResourceID) + ":" + rootField.id.Name
|
|
181
|
+
prevSubscriptions := ctxStorageResource.kvGetAsJson(pssKey)
|
|
182
|
+
|
|
183
|
+
if !is_undefined(prevSubscriptions) && len(prevSubscriptions) == 0 {
|
|
184
|
+
// initialization was finished before, in a previous template execution
|
|
185
|
+
ll.panic("Unexpected state, desired state was reached in the previous call")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if is_undefined(prevSubscriptions) {
|
|
189
|
+
// initializing previous subscriptions set
|
|
190
|
+
prevSubscriptions = {}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
subscriptions := {}
|
|
194
|
+
|
|
195
|
+
addSubscription := func(subscription) {
|
|
196
|
+
key := string(subscription.resource) + ":" + subscription.event
|
|
197
|
+
if !is_undefined(subscriptions[key]) {
|
|
198
|
+
return false
|
|
199
|
+
} else {
|
|
200
|
+
subscriptions[key] = subscription
|
|
201
|
+
return true
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for _, request in requests {
|
|
206
|
+
if !is_map(request) || !is_array(request.path) || !is_string(request.state) {
|
|
207
|
+
ll.panic("Malformed state await request: %v", request)
|
|
208
|
+
}
|
|
209
|
+
res := awaitOneState(rootField, request.path, request.state)
|
|
210
|
+
if res.type == "Ready" {
|
|
211
|
+
continue
|
|
212
|
+
} else if res.type == "Subscribe" {
|
|
213
|
+
for subscription in res.subscriptions {
|
|
214
|
+
addSubscription(subscription)
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
ll.panic("Unknown result type %v", res.type)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// creating new subscriptions
|
|
222
|
+
for key, sub in subscriptions {
|
|
223
|
+
if !is_undefined(prevSubscriptions[key]) {
|
|
224
|
+
// don't create subscription, if it was created in the past
|
|
225
|
+
continue
|
|
226
|
+
}
|
|
227
|
+
e := {}
|
|
228
|
+
e[sub.event] = true
|
|
229
|
+
tx.subscribeTo(sub.resource, pssKey + ":" + key, e)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// unsubscribing from subscriptions we don't need anymore
|
|
233
|
+
for key, _ in prevSubscriptions {
|
|
234
|
+
if !is_undefined(subscriptions[key]) {
|
|
235
|
+
// don't unsubscribe from subscriptions, we still need
|
|
236
|
+
continue
|
|
237
|
+
}
|
|
238
|
+
tx.unsubscribeFrom(pssKey + ":" + key)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// creating and saving new context; savong only keys
|
|
242
|
+
newPrevSubscriptions := {}
|
|
243
|
+
for key, _ in subscriptions {
|
|
244
|
+
newPrevSubscriptions[key] = true
|
|
245
|
+
}
|
|
246
|
+
// saving the context
|
|
247
|
+
ctxStorageResource.kvSetJson(pssKey, newPrevSubscriptions)
|
|
248
|
+
|
|
249
|
+
return len(subscriptions) == 0
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
export ll.toStrict({
|
|
253
|
-
await: await
|
|
253
|
+
await: await
|
|
254
254
|
})
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/* Templates/renderers utils */
|
|
2
2
|
|
|
3
3
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// template field name in renderer resource
|
|
6
6
|
TEMPLATE_FIELD := "template"
|
|
7
|
-
|
|
7
|
+
// field name of a resource map with the inputs in renderer resource
|
|
8
8
|
INPUTS_MAP_FIELD := "inputs"
|
|
9
|
-
|
|
9
|
+
// prefix of output fields template results in renderer resource
|
|
10
10
|
TEMPLATE_OUTPUT_PREFIX := "outputs/"
|
|
11
|
-
|
|
11
|
+
// input field containing a map with resources to prepare for the body
|
|
12
12
|
PREPARE_MAP_FIELD_NAME := "__prepare__"
|
|
13
13
|
|
|
14
14
|
export ll.toStrict({
|
|
15
|
-
TEMPLATE_FIELD : TEMPLATE_FIELD,
|
|
16
|
-
INPUTS_MAP_FIELD : INPUTS_MAP_FIELD,
|
|
17
|
-
TEMPLATE_OUTPUT_PREFIX : TEMPLATE_OUTPUT_PREFIX,
|
|
18
|
-
PREPARE_MAP_FIELD_NAME : PREPARE_MAP_FIELD_NAME
|
|
15
|
+
TEMPLATE_FIELD : TEMPLATE_FIELD,
|
|
16
|
+
INPUTS_MAP_FIELD : INPUTS_MAP_FIELD,
|
|
17
|
+
TEMPLATE_OUTPUT_PREFIX : TEMPLATE_OUTPUT_PREFIX,
|
|
18
|
+
PREPARE_MAP_FIELD_NAME : PREPARE_MAP_FIELD_NAME
|
|
19
19
|
})
|