ad8809efb7
To fix a potential temporary goroutine leak; see the added comment. The leaked goroutine would eventually stop once the timer is fired, but until then, the goroutine could be unnecessarily left around.
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
package chromedp
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/chromedp/cdproto/cdp"
|
|
)
|
|
|
|
// Action is the common interface for an action that will be executed against a
|
|
// context and frame handler.
|
|
type Action interface {
|
|
// Do executes the action using the provided context and frame handler.
|
|
Do(context.Context, cdp.Executor) error
|
|
}
|
|
|
|
// ActionFunc is a adapter to allow the use of ordinary func's as an Action.
|
|
type ActionFunc func(context.Context, cdp.Executor) error
|
|
|
|
// Do executes the func f using the provided context and frame handler.
|
|
func (f ActionFunc) Do(ctx context.Context, h cdp.Executor) error {
|
|
return f(ctx, h)
|
|
}
|
|
|
|
// Tasks is a sequential list of Actions that can be used as a single Action.
|
|
type Tasks []Action
|
|
|
|
// Do executes the list of Actions sequentially, using the provided context and
|
|
// frame handler.
|
|
func (t Tasks) Do(ctx context.Context, h cdp.Executor) error {
|
|
// TODO: put individual task timeouts from context here
|
|
for _, a := range t {
|
|
// ctx, cancel = context.WithTimeout(ctx, timeout)
|
|
// defer cancel()
|
|
if err := a.Do(ctx, h); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Sleep is an empty action that calls time.Sleep with the specified duration.
|
|
//
|
|
// Note: this is a temporary action definition for convenience, and will likely
|
|
// be marked for deprecation in the future, after the remaining Actions have
|
|
// been able to be written/tested.
|
|
func Sleep(d time.Duration) Action {
|
|
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
|
|
// Don't use time.After, to avoid a temporary goroutine leak if
|
|
// ctx is cancelled before the timer fires.
|
|
t := time.NewTimer(d)
|
|
select {
|
|
case <-t.C:
|
|
case <-ctx.Done():
|
|
t.Stop()
|
|
return ctx.Err()
|
|
}
|
|
return nil
|
|
})
|
|
}
|