github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/ratelimiter/period_manager.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 ratelimiter
     7  
     8  import (
     9  	"sync"
    10  
    11  	"github.com/insolar/vanilla/atomickit"
    12  	"github.com/insolar/vanilla/throw"
    13  )
    14  
    15  func NewPeriodManager(scale uint32) (*PeriodManager, func(uint)) {
    16  	if scale == 0 {
    17  		panic(throw.IllegalValue())
    18  	}
    19  	bm := &PeriodManager{amountScale: scale}
    20  	bm.init()
    21  	return bm, bm.nextPeriod
    22  }
    23  
    24  type PeriodManager struct {
    25  	currentPeriod atomickit.Uint64
    26  	signal        sync.Mutex
    27  	amountScale   uint32
    28  }
    29  
    30  func (p *PeriodManager) init() {
    31  	if p.currentPeriod.Load() != 0 {
    32  		panic(throw.IllegalState())
    33  	}
    34  	p.signal.Lock()
    35  	p.nextPeriod(1)
    36  }
    37  
    38  func (p *PeriodManager) nextPeriod(increment uint) {
    39  	p.currentPeriod.Add(uint64(increment))
    40  	p.signal.Unlock()
    41  	p.signal.Lock()
    42  }
    43  
    44  func (p *PeriodManager) waitNextPeriod(x uint64) {
    45  	if p.currentPeriod.Load() != x {
    46  		return
    47  	}
    48  	p.signal.Lock()
    49  	p.currentPeriod.Load() // to avoid lint:staticcheck
    50  	p.signal.Unlock()
    51  }
    52  
    53  func (p *PeriodManager) NewBucket(cfg bucketConfig) *Bucket {
    54  	return NewBucket(p, cfg)
    55  }
    56  
    57  func (p *PeriodManager) NewRWBucket(cfgR, cfgW bucketConfig) *RWBucket {
    58  	return NewRWBucket(p, cfgR, cfgW)
    59  }