github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/synckit/occasion.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package synckit
     7  
     8  import "time"
     9  
    10  type Occasion interface {
    11  	Deadline() time.Time
    12  	NewTimer() TimerHolder
    13  	NewFunc(fn func()) TimerHolder
    14  	IsExpired() bool
    15  }
    16  
    17  type TimerHolder interface {
    18  	Channel() <-chan time.Time
    19  	Stop()
    20  }
    21  
    22  func Never() TimerHolder {
    23  	return (*timerWithChan)(nil)
    24  }
    25  
    26  func NewTimer(d time.Duration) TimerHolder {
    27  	return &timerWithChan{time.NewTimer(d)}
    28  }
    29  
    30  func NewTimerWithFunc(d time.Duration, fn func()) TimerHolder {
    31  	return &timerWithFn{time.AfterFunc(d, fn)}
    32  }
    33  
    34  type timerWithChan struct {
    35  	t *time.Timer
    36  }
    37  
    38  func (p *timerWithChan) Channel() <-chan time.Time {
    39  	if p == nil || p.t == nil {
    40  		return nil
    41  	}
    42  	return p.t.C
    43  }
    44  
    45  func (p *timerWithChan) Stop() {
    46  	if p == nil || p.t == nil {
    47  		return
    48  	}
    49  	p.t.Stop()
    50  }
    51  
    52  type timerWithFn struct {
    53  	t *time.Timer
    54  }
    55  
    56  func (p *timerWithFn) Channel() <-chan time.Time {
    57  	panic("illegal state")
    58  }
    59  
    60  func (p *timerWithFn) Stop() {
    61  	p.t.Stop()
    62  }
    63  
    64  func NewOccasion(deadline time.Time) Occasion {
    65  	return factory{deadline}
    66  }
    67  
    68  func NewOccasionAfter(d time.Duration) Occasion {
    69  	return factory{time.Now().Add(d)}
    70  }
    71  
    72  type factory struct {
    73  	d time.Time
    74  }
    75  
    76  func (p factory) IsExpired() bool {
    77  	return p.d.Before(time.Now())
    78  }
    79  
    80  func (p factory) Deadline() time.Time {
    81  	return p.d
    82  }
    83  
    84  func (p factory) NewTimer() TimerHolder {
    85  	return NewTimer(time.Until(p.d))
    86  }
    87  
    88  func (p factory) NewFunc(fn func()) TimerHolder {
    89  	return NewTimerWithFunc(time.Until(p.d), fn)
    90  }
    91  
    92  func NeverOccasion() Occasion {
    93  	return factoryNever{}
    94  }
    95  
    96  type factoryNever struct{}
    97  
    98  func (factoryNever) IsExpired() bool {
    99  	return false
   100  }
   101  
   102  func (factoryNever) Deadline() time.Time {
   103  	return time.Time{}
   104  }
   105  
   106  func (factoryNever) NewTimer() TimerHolder {
   107  	return Never()
   108  }
   109  
   110  func (factoryNever) NewFunc(fn func()) TimerHolder {
   111  	return Never()
   112  }
   113  
   114  func EverOccasion() Occasion {
   115  	return factoryEver{}
   116  }
   117  
   118  type factoryEver struct {
   119  }
   120  
   121  func (factoryEver) IsExpired() bool {
   122  	return true
   123  }
   124  
   125  func (factoryEver) Deadline() time.Time {
   126  	return time.Time{}
   127  }
   128  
   129  func (factoryEver) NewTimer() TimerHolder {
   130  	return NewTimer(0)
   131  }
   132  
   133  func (factoryEver) NewFunc(fn func()) TimerHolder {
   134  	go fn()
   135  	return Never()
   136  }