mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-14 11:23:02 +02:00
8e13cf9134
* Refactored input and select * WIP * Fixed serialization * Fixed scriolling * Fixed XPath result handling * Renamed some methods
111 lines
2.1 KiB
Go
111 lines
2.1 KiB
Go
package events
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/MontFerret/ferret/pkg/drivers"
|
|
"github.com/MontFerret/ferret/pkg/drivers/cdp/eval"
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
|
)
|
|
|
|
type (
|
|
Function func(ctx context.Context) (core.Value, error)
|
|
|
|
WaitTask struct {
|
|
fun Function
|
|
polling time.Duration
|
|
}
|
|
)
|
|
|
|
const DefaultPolling = time.Millisecond * time.Duration(200)
|
|
|
|
func NewWaitTask(
|
|
fun Function,
|
|
polling time.Duration,
|
|
) *WaitTask {
|
|
return &WaitTask{
|
|
fun,
|
|
polling,
|
|
}
|
|
}
|
|
|
|
func (task *WaitTask) Run(ctx context.Context) (core.Value, error) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return values.None, core.ErrTimeout
|
|
default:
|
|
out, err := task.fun(ctx)
|
|
|
|
// expression failed
|
|
// terminating
|
|
if err != nil {
|
|
return values.None, err
|
|
}
|
|
|
|
// output is not empty
|
|
// terminating
|
|
if out != values.None {
|
|
return out, nil
|
|
}
|
|
|
|
// Nothing yet, let's wait before the next try
|
|
time.Sleep(task.polling)
|
|
}
|
|
}
|
|
}
|
|
|
|
func NewEvalWaitTask(
|
|
ec *eval.ExecutionContext,
|
|
predicate string,
|
|
polling time.Duration,
|
|
) *WaitTask {
|
|
return NewWaitTask(
|
|
func(ctx context.Context) (core.Value, error) {
|
|
return ec.EvalWithReturnValue(
|
|
ctx,
|
|
predicate,
|
|
)
|
|
},
|
|
polling,
|
|
)
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|