github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/ratelimit/bandwidth.go (about)

     1  // Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package ratelimit
     4  
     5  import (
     6  	"context"
     7  	"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
     8  	"sync/atomic"
     9  	"time"
    10  )
    11  
    12  // Bandwidth lossy bandwidth limiter
    13  type Bandwidth struct {
    14  	totalBytes int64
    15  
    16  	currentTimestamp int64
    17  	currentBytes     int64
    18  }
    19  
    20  // NewBandwidth create new bandwidth limiter
    21  func NewBandwidth(totalBytes int64) *Bandwidth {
    22  	return &Bandwidth{totalBytes: totalBytes}
    23  }
    24  
    25  // Ack acquire next chance to send data
    26  func (this *Bandwidth) Ack(ctx context.Context, newBytes int) {
    27  	if newBytes <= 0 {
    28  		return
    29  	}
    30  	if this.totalBytes <= 0 {
    31  		return
    32  	}
    33  
    34  	var timestamp = fasttime.Now().Unix()
    35  	if this.currentTimestamp != 0 && this.currentTimestamp != timestamp {
    36  		this.currentTimestamp = timestamp
    37  		this.currentBytes = int64(newBytes)
    38  
    39  		// 第一次发送直接放行,不需要判断
    40  		return
    41  	}
    42  
    43  	if this.currentTimestamp == 0 {
    44  		this.currentTimestamp = timestamp
    45  	}
    46  	if atomic.AddInt64(&this.currentBytes, int64(newBytes)) <= this.totalBytes {
    47  		return
    48  	}
    49  
    50  	var timeout = time.NewTimer(1 * time.Second)
    51  	if ctx != nil {
    52  		select {
    53  		case <-timeout.C:
    54  		case <-ctx.Done():
    55  		}
    56  	} else {
    57  		select {
    58  		case <-timeout.C:
    59  		}
    60  	}
    61  }