@@ -41,6 +41,7 @@ import (
4141 "github.com/AliceO2Group/Control/core/task"
4242 "github.com/AliceO2Group/Control/core/the"
4343 "github.com/AliceO2Group/Control/core/workflow"
44+ "github.com/AliceO2Group/Control/core/workflow/callable"
4445 "github.com/gobwas/glob"
4546 "github.com/looplab/fsm"
4647 "github.com/pborman/uuid"
@@ -69,6 +70,8 @@ type Environment struct {
6970 stateChangedCh chan * event.TasksStateChangedEvent
7071 unsubscribe chan struct {}
7172 eventStream Subscription
73+
74+ callsPendingAwait map [string /*await expression*/ ]callable.Calls
7275}
7376
7477func (env * Environment ) NotifyEvent (e event.DeviceEvent ) {
@@ -93,6 +96,8 @@ func newEnvironment(userVars map[string]string) (env *Environment, err error) {
9396 GlobalVars : gera .MakeStringMapWithMap (the .ConfSvc ().GetVars ()),
9497 UserVars : gera .MakeStringMapWithMap (userVars ),
9598 stateChangedCh : make (chan * event.TasksStateChangedEvent ),
99+
100+ callsPendingAwait : make (map [string ]callable.Calls ),
96101 }
97102
98103 // Make the KVs accessible to the workflow via ParentAdapter
@@ -160,10 +165,35 @@ func newEnvironment(userVars map[string]string) (env *Environment, err error) {
160165}
161166
162167func (env * Environment ) handleHooks (workflow workflow.Role , trigger string ) (err error ) {
168+ // First we start any tasks
163169 allHooks := workflow .GetHooksForTrigger (trigger )
164- allHooks .FilterCalls ().CallAll ()
170+ callsToStart := allHooks .FilterCalls ()
171+ if len (callsToStart ) != 0 {
172+ // Before we run anything asynchronously we must associate each call we're about
173+ // to start with its corresponding await expression
174+ for _ , call := range callsToStart {
175+ awaitExpr := call .GetTraits ().Await
176+ if _ , ok := env .callsPendingAwait [awaitExpr ]; ! ok || len (env .callsPendingAwait [awaitExpr ]) == 0 {
177+ env .callsPendingAwait [awaitExpr ] = make (callable.Calls , 0 )
178+ }
179+ env .callsPendingAwait [awaitExpr ] = append (env .callsPendingAwait [awaitExpr ], call )
180+ }
181+ callsToStart .StartAll ()
182+ }
165183
184+ // Then we take care of any pending hooks, including from the current trigger
185+ // TODO: this should be further refined by adding priority/weight
186+ pendingCalls , ok := env .callsPendingAwait [trigger ]
187+ if ok && len (pendingCalls ) != 0 { // there are hooks to take care of
188+ pendingCalls .AwaitAll ()
189+ }
190+
191+ // Tasks are handled separately for now, and they cannot have trigger!=await
166192 hooksToTrigger := allHooks .FilterTasks ()
193+ return env .runTasksAsHooks (hooksToTrigger )
194+ }
195+
196+ func (env * Environment ) runTasksAsHooks (hooksToTrigger task.Tasks ) (err error ) {
167197 if len (hooksToTrigger ) == 0 {
168198 return nil
169199 }
@@ -190,7 +220,7 @@ func (env *Environment) handleHooks(workflow workflow.Role, trigger string) (err
190220
191221 for {
192222 select {
193- case e := <- env .incomingEvents :
223+ case e := <- env .incomingEvents :
194224 switch evt := e .(type ) {
195225 case * event.BasicTaskTerminated :
196226 tid := evt .GetOrigin ().TaskId
@@ -205,10 +235,10 @@ func (env *Environment) handleHooks(workflow workflow.Role, trigger string) (err
205235 failedHooksById [thisHook .GetTaskId ()] = thisHook
206236 log .WithField ("task" , thisHook .GetName ()).
207237 WithFields (logrus.Fields {
208- "exitCode" : evt .ExitCode ,
209- "stdout" : evt .Stdout ,
210- "stderr" : evt .Stderr ,
211- "partition" : env .Id ().String (),
238+ "exitCode" : evt .ExitCode ,
239+ "stdout" : evt .Stdout ,
240+ "stderr" : evt .Stderr ,
241+ "partition" : env .Id ().String (),
212242 "finalMesosState" : evt .FinalMesosState .String (),
213243 }).
214244 Warn ("hook failed" )
@@ -221,7 +251,7 @@ func (env *Environment) handleHooks(workflow workflow.Role, trigger string) (err
221251 default :
222252 continue
223253 }
224- case thisHook := <- timeoutCh :
254+ case thisHook := <- timeoutCh :
225255 log .WithField ("partition" , env .Id ().String ()).
226256 WithField ("task" , thisHook .GetName ()).Warn ("hook response timed out" )
227257 delete (hookTimers , thisHook )
0 commit comments