diff --git a/internal/caches/max_open_files.go b/internal/caches/max_open_files.go index 95b114a..35b8dc5 100644 --- a/internal/caches/max_open_files.go +++ b/internal/caches/max_open_files.go @@ -13,16 +13,20 @@ const ( minOpenFilesValue int32 = 2 maxOpenFilesValue int32 = 65535 - modSlow int32 = 1 - modFast int32 = 2 + modeSlow int32 = 1 + modeFast int32 = 2 ) +// MaxOpenFiles max open files manager type MaxOpenFiles struct { step int32 maxOpenFiles int32 ptr *int32 ticker *time.Ticker - mod int32 + mode int32 + + lastOpens int32 + currentOpens int32 } func NewMaxOpenFiles(step int32) *MaxOpenFiles { @@ -38,40 +42,51 @@ func NewMaxOpenFiles(step int32) *MaxOpenFiles { } f.ptr = &f.maxOpenFiles f.ticker = time.NewTicker(1 * time.Second) - goman.New(func() { - for range f.ticker.C { - var mod = atomic.LoadInt32(&f.mod) - switch mod { - case modSlow: - // we decrease more quickly, with more steps - if atomic.AddInt32(f.ptr, -step*2) <= 0 { - atomic.StoreInt32(f.ptr, minOpenFilesValue) - } - case modFast: - if atomic.AddInt32(f.ptr, step) >= maxOpenFilesValue { - atomic.StoreInt32(f.ptr, maxOpenFilesValue) - } - } - - // reset mod - atomic.StoreInt32(&f.mod, 0) - } - }) + f.init() return f } +func (this *MaxOpenFiles) init() { + goman.New(func() { + for range this.ticker.C { + var mod = atomic.LoadInt32(&this.mode) + switch mod { + case modeSlow: + // we decrease more quickly, with more steps + if atomic.AddInt32(this.ptr, -this.step*2) <= 0 { + atomic.StoreInt32(this.ptr, minOpenFilesValue) + } + case modeFast: + // we increase only when file opens increases + var currentOpens = atomic.LoadInt32(&this.currentOpens) + if currentOpens > this.lastOpens { + if atomic.AddInt32(this.ptr, this.step) >= maxOpenFilesValue { + atomic.StoreInt32(this.ptr, maxOpenFilesValue) + } + } + this.lastOpens = currentOpens + atomic.StoreInt32(&this.currentOpens, 0) + } + + // reset mod + atomic.StoreInt32(&this.mode, 0) + } + }) +} + func (this *MaxOpenFiles) Fast() { - if atomic.LoadInt32(&this.mod) == 0 { - this.mod = modFast + if atomic.LoadInt32(&this.mode) == 0 { + this.mode = modeFast } + atomic.AddInt32(&this.currentOpens, 1) } func (this *MaxOpenFiles) Slow() { - atomic.StoreInt32(&this.mod, modSlow) + atomic.StoreInt32(&this.mode, modeSlow) } func (this *MaxOpenFiles) Max() int32 { - if atomic.LoadInt32(&this.mod) == modSlow { + if atomic.LoadInt32(&this.mode) == modeSlow { return 0 }