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  }