mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
						|
 | 
						|
package fsutils
 | 
						|
 | 
						|
import (
 | 
						|
	"runtime"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
var maxThreads = runtime.NumCPU()
 | 
						|
var WriterLimiter = NewLimiter(maxThreads)
 | 
						|
var ReaderLimiter = NewLimiter(maxThreads)
 | 
						|
 | 
						|
type Limiter struct {
 | 
						|
	threads chan struct{}
 | 
						|
	timers  chan *time.Timer
 | 
						|
}
 | 
						|
 | 
						|
func NewLimiter(threads int) *Limiter {
 | 
						|
	if threads < 4 {
 | 
						|
		threads = 4
 | 
						|
	}
 | 
						|
	if threads > 32 {
 | 
						|
		threads = 32
 | 
						|
	}
 | 
						|
 | 
						|
	var threadsChan = make(chan struct{}, threads)
 | 
						|
	for i := 0; i < threads; i++ {
 | 
						|
		threadsChan <- struct{}{}
 | 
						|
	}
 | 
						|
 | 
						|
	return &Limiter{
 | 
						|
		threads: threadsChan,
 | 
						|
		timers:  make(chan *time.Timer, 2048),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (this *Limiter) Ack() {
 | 
						|
	<-this.threads
 | 
						|
}
 | 
						|
 | 
						|
func (this *Limiter) TryAck() bool {
 | 
						|
	const timeoutDuration = 500 * time.Millisecond
 | 
						|
 | 
						|
	var timeout *time.Timer
 | 
						|
	select {
 | 
						|
	case timeout = <-this.timers:
 | 
						|
		timeout.Reset(timeoutDuration)
 | 
						|
	default:
 | 
						|
		timeout = time.NewTimer(timeoutDuration)
 | 
						|
	}
 | 
						|
 | 
						|
	defer func() {
 | 
						|
		timeout.Stop()
 | 
						|
 | 
						|
		select {
 | 
						|
		case this.timers <- timeout:
 | 
						|
		default:
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	select {
 | 
						|
	case <-this.threads:
 | 
						|
		return true
 | 
						|
	case <-timeout.C:
 | 
						|
		return false
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (this *Limiter) Release() {
 | 
						|
	this.threads <- struct{}{}
 | 
						|
}
 |