2018-09-25 23:58:57 +02:00
|
|
|
package events
|
2018-09-23 10:33:20 +02:00
|
|
|
|
|
|
|
import (
|
2019-02-21 04:24:05 +02:00
|
|
|
"context"
|
2019-06-19 23:58:56 +02:00
|
|
|
"time"
|
|
|
|
|
2019-03-15 04:10:15 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/drivers"
|
2018-12-22 06:14:41 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/drivers/cdp/eval"
|
2018-09-23 10:33:20 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
|
|
|
)
|
|
|
|
|
2018-10-07 04:33:39 +02:00
|
|
|
type (
|
2019-02-21 04:24:05 +02:00
|
|
|
Function func(ctx context.Context) (core.Value, error)
|
|
|
|
|
2018-10-07 04:33:39 +02:00
|
|
|
WaitTask struct {
|
|
|
|
fun Function
|
|
|
|
polling time.Duration
|
|
|
|
}
|
|
|
|
)
|
2018-09-23 10:33:20 +02:00
|
|
|
|
2018-09-25 17:43:58 +02:00
|
|
|
const DefaultPolling = time.Millisecond * time.Duration(200)
|
|
|
|
|
2018-09-23 10:33:20 +02:00
|
|
|
func NewWaitTask(
|
2018-10-07 04:33:39 +02:00
|
|
|
fun Function,
|
2018-09-25 17:43:58 +02:00
|
|
|
polling time.Duration,
|
2018-09-23 10:33:20 +02:00
|
|
|
) *WaitTask {
|
|
|
|
return &WaitTask{
|
2018-10-07 04:33:39 +02:00
|
|
|
fun,
|
2018-09-25 17:43:58 +02:00
|
|
|
polling,
|
2018-09-23 10:33:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-21 04:24:05 +02:00
|
|
|
func (task *WaitTask) Run(ctx context.Context) (core.Value, error) {
|
2018-09-25 17:43:58 +02:00
|
|
|
for {
|
2018-09-23 10:33:20 +02:00
|
|
|
select {
|
2019-02-21 04:24:05 +02:00
|
|
|
case <-ctx.Done():
|
2018-09-25 17:43:58 +02:00
|
|
|
return values.None, core.ErrTimeout
|
2018-09-23 10:33:20 +02:00
|
|
|
default:
|
2019-02-21 04:24:05 +02:00
|
|
|
out, err := task.fun(ctx)
|
2018-09-23 10:33:20 +02:00
|
|
|
|
2018-10-07 04:33:39 +02:00
|
|
|
// expression failed
|
2018-09-25 17:43:58 +02:00
|
|
|
// terminating
|
|
|
|
if err != nil {
|
|
|
|
return values.None, err
|
2018-09-23 10:33:20 +02:00
|
|
|
}
|
|
|
|
|
2018-10-07 04:33:39 +02:00
|
|
|
// output is not empty
|
2018-09-25 17:43:58 +02:00
|
|
|
// terminating
|
2018-09-23 10:33:20 +02:00
|
|
|
if out != values.None {
|
2018-09-25 17:43:58 +02:00
|
|
|
return out, nil
|
2018-09-23 10:33:20 +02:00
|
|
|
}
|
2018-09-25 17:43:58 +02:00
|
|
|
|
|
|
|
// Nothing yet, let's wait before the next try
|
|
|
|
time.Sleep(task.polling)
|
2018-09-23 10:33:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-07 04:33:39 +02:00
|
|
|
|
|
|
|
func NewEvalWaitTask(
|
2019-06-19 23:58:56 +02:00
|
|
|
ec *eval.ExecutionContext,
|
2018-10-07 04:33:39 +02:00
|
|
|
predicate string,
|
|
|
|
polling time.Duration,
|
|
|
|
) *WaitTask {
|
|
|
|
return NewWaitTask(
|
2019-02-21 04:24:05 +02:00
|
|
|
func(ctx context.Context) (core.Value, error) {
|
2019-07-17 00:17:42 +02:00
|
|
|
return ec.EvalWithReturnValue(
|
2019-02-21 04:24:05 +02:00
|
|
|
ctx,
|
2018-10-07 04:33:39 +02:00
|
|
|
predicate,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
polling,
|
|
|
|
)
|
|
|
|
}
|
2019-03-15 04:10:15 +02:00
|
|
|
|
|
|
|
func NewValueWaitTask(
|
|
|
|
when drivers.WaitEvent,
|
|
|
|
value core.Value,
|
|
|
|
getter Function,
|
|
|
|
polling time.Duration,
|
|
|
|
) *WaitTask {
|
|
|
|
return &WaitTask{
|
|
|
|
func(ctx context.Context) (core.Value, error) {
|
|
|
|
current, err := getter(ctx)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return values.None, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if when == drivers.WaitEventPresence {
|
|
|
|
// Values appeared, exit
|
|
|
|
if current.Compare(value) == 0 {
|
|
|
|
// The value does not really matter if it's not None
|
|
|
|
// None indicates that operation needs to be repeated
|
|
|
|
return values.True, nil
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Value disappeared, exit
|
|
|
|
if current.Compare(value) != 0 {
|
|
|
|
// The value does not really matter if it's not None
|
|
|
|
// None indicates that operation needs to be repeated
|
|
|
|
return values.True, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.None, nil
|
|
|
|
},
|
|
|
|
polling,
|
|
|
|
}
|
|
|
|
}
|