github.com/iotexproject/iotex-core@v1.14.1-rc1/pkg/routine/delaytask.go (about) 1 // Copyright (c) 2018 IoTeX 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package routine 7 8 import ( 9 "context" 10 "time" 11 12 "github.com/facebookgo/clock" 13 14 "github.com/iotexproject/iotex-core/pkg/lifecycle" 15 ) 16 17 var _ lifecycle.StartStopper = (*DelayTask)(nil) 18 19 // DelayTaskOption is option to DelayTask. 20 type DelayTaskOption interface { 21 SetDelayTaskOption(*DelayTask) 22 } 23 24 // DelayTask represents a timeout task 25 type DelayTask struct { 26 cb Task 27 duration time.Duration 28 ch chan interface{} 29 clock clock.Clock 30 } 31 32 // NewDelayTask creates an instance of DelayTask 33 func NewDelayTask(cb Task, d time.Duration, ops ...DelayTaskOption) *DelayTask { 34 dt := &DelayTask{ 35 cb: cb, 36 duration: d, 37 ch: make(chan interface{}, 1), 38 clock: clock.New(), 39 } 40 for _, opt := range ops { 41 opt.SetDelayTaskOption(dt) 42 } 43 return dt 44 } 45 46 // Start executes the delayed task after given timeout. 47 func (t *DelayTask) Start(ctx context.Context) error { 48 ready := make(chan struct{}) 49 go func() { 50 close(ready) 51 select { 52 case <-ctx.Done(): 53 return 54 case <-t.ch: 55 return 56 case <-t.clock.After(t.duration): 57 t.cb() 58 } 59 }() 60 61 <-ready 62 return nil 63 } 64 65 // Stop stops the timeout 66 func (t *DelayTask) Stop(ctx context.Context) error { 67 t.ch <- struct{}{} 68 return nil 69 }