mirror of
https://github.com/ehang-io/nps.git
synced 2025-07-03 04:53:50 +00:00
fine bandwidth calculation, fix slide window calculated size too large, fix #330
This commit is contained in:
parent
258be8e67a
commit
076fc8b2e1
@ -246,6 +246,15 @@ func (Self *MuxPackager) UnPack(reader io.Reader) (n uint16, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Self *MuxPackager) reset() {
|
||||||
|
Self.Id = 0
|
||||||
|
Self.Flag = 0
|
||||||
|
Self.Length = 0
|
||||||
|
Self.Content = nil
|
||||||
|
Self.ReadLength = 0
|
||||||
|
Self.Window = 0
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ipV4 = 1
|
ipV4 = 1
|
||||||
domainName = 3
|
domainName = 3
|
||||||
|
@ -93,18 +93,20 @@ type windowBufferPool struct {
|
|||||||
func (Self *windowBufferPool) New() {
|
func (Self *windowBufferPool) New() {
|
||||||
Self.pool = sync.Pool{
|
Self.pool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return make([]byte, PoolSizeWindow, PoolSizeWindow)
|
return make([]byte, PoolSizeWindow)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Self *windowBufferPool) Get() (buf []byte) {
|
func (Self *windowBufferPool) Get() (buf []byte) {
|
||||||
buf = Self.pool.Get().([]byte)
|
buf = Self.pool.Get().([]byte)
|
||||||
return buf[:PoolSizeWindow]
|
buf = buf[:PoolSizeWindow]
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Self *windowBufferPool) Put(x []byte) {
|
func (Self *windowBufferPool) Put(x []byte) {
|
||||||
Self.pool.Put(x[:PoolSizeWindow]) // make buf to full
|
x = x[:0] // clean buf
|
||||||
|
Self.pool.Put(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
type bufferPool struct {
|
type bufferPool struct {
|
||||||
@ -146,6 +148,7 @@ func (Self *muxPackagerPool) Get() *MuxPackager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (Self *muxPackagerPool) Put(pack *MuxPackager) {
|
func (Self *muxPackagerPool) Put(pack *MuxPackager) {
|
||||||
|
pack.reset()
|
||||||
Self.pool.Put(pack)
|
Self.pool.Put(pack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package mux
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/astaxie/beego/logs"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
@ -215,10 +216,10 @@ func (Self *ReceiveWindow) calcSize() {
|
|||||||
if n < common.MAXIMUM_SEGMENT_SIZE*10 {
|
if n < common.MAXIMUM_SEGMENT_SIZE*10 {
|
||||||
n = common.MAXIMUM_SEGMENT_SIZE * 10
|
n = common.MAXIMUM_SEGMENT_SIZE * 10
|
||||||
}
|
}
|
||||||
bufLen := Self.bufQueue.Len()
|
//bufLen := Self.bufQueue.Len()
|
||||||
if n < bufLen {
|
//if n < bufLen {
|
||||||
n = bufLen
|
// n = bufLen
|
||||||
}
|
//}
|
||||||
if n < Self.maxSize/2 {
|
if n < Self.maxSize/2 {
|
||||||
n = Self.maxSize / 2
|
n = Self.maxSize / 2
|
||||||
}
|
}
|
||||||
@ -227,6 +228,7 @@ func (Self *ReceiveWindow) calcSize() {
|
|||||||
n = 2 * Self.maxSize
|
n = 2 * Self.maxSize
|
||||||
}
|
}
|
||||||
if n > (common.MAXIMUM_WINDOW_SIZE / uint32(conns)) {
|
if n > (common.MAXIMUM_WINDOW_SIZE / uint32(conns)) {
|
||||||
|
logs.Warn("window too large", n)
|
||||||
n = common.MAXIMUM_WINDOW_SIZE / uint32(conns)
|
n = common.MAXIMUM_WINDOW_SIZE / uint32(conns)
|
||||||
}
|
}
|
||||||
// set the maximum size
|
// set the maximum size
|
||||||
|
@ -5,7 +5,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego/logs"
|
"github.com/astaxie/beego/logs"
|
||||||
@ -35,13 +37,17 @@ func NewMux(c net.Conn, connType string) *Mux {
|
|||||||
//c.(*net.TCPConn).SetReadBuffer(0)
|
//c.(*net.TCPConn).SetReadBuffer(0)
|
||||||
//c.(*net.TCPConn).SetWriteBuffer(0)
|
//c.(*net.TCPConn).SetWriteBuffer(0)
|
||||||
_ = c.SetDeadline(time.Time{})
|
_ = c.SetDeadline(time.Time{})
|
||||||
|
fd, err := getConnFd(c)
|
||||||
|
if err != nil {
|
||||||
|
logs.Warn(err)
|
||||||
|
}
|
||||||
m := &Mux{
|
m := &Mux{
|
||||||
conn: c,
|
conn: c,
|
||||||
connMap: NewConnMap(),
|
connMap: NewConnMap(),
|
||||||
id: 0,
|
id: 0,
|
||||||
closeChan: make(chan struct{}, 1),
|
closeChan: make(chan struct{}, 1),
|
||||||
newConnCh: make(chan *conn),
|
newConnCh: make(chan *conn),
|
||||||
bw: new(bandwidth),
|
bw: NewBandwidth(fd),
|
||||||
IsClose: false,
|
IsClose: false,
|
||||||
connType: connType,
|
connType: connType,
|
||||||
pingCh: make(chan []byte),
|
pingCh: make(chan []byte),
|
||||||
@ -58,6 +64,26 @@ func NewMux(c net.Conn, connType string) *Mux {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getConnFd(c net.Conn) (fd *os.File, err error) {
|
||||||
|
switch c.(type) {
|
||||||
|
case *net.TCPConn:
|
||||||
|
fd, err = c.(*net.TCPConn).File()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case *net.UDPConn:
|
||||||
|
fd, err = c.(*net.UDPConn).File()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
err = errors.New("mux:unknown conn type, only tcp or kcp")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Mux) NewConn() (*conn, error) {
|
func (s *Mux) NewConn() (*conn, error) {
|
||||||
if s.IsClose {
|
if s.IsClose {
|
||||||
return nil, errors.New("the mux has closed")
|
return nil, errors.New("the mux has closed")
|
||||||
@ -392,13 +418,19 @@ type bandwidth struct {
|
|||||||
readStart time.Time
|
readStart time.Time
|
||||||
lastReadStart time.Time
|
lastReadStart time.Time
|
||||||
bufLength uint32
|
bufLength uint32
|
||||||
|
fd *os.File
|
||||||
|
calcThreshold uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBandwidth(fd *os.File) *bandwidth {
|
||||||
|
return &bandwidth{fd: fd}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Self *bandwidth) StartRead() {
|
func (Self *bandwidth) StartRead() {
|
||||||
if Self.readStart.IsZero() {
|
if Self.readStart.IsZero() {
|
||||||
Self.readStart = time.Now()
|
Self.readStart = time.Now()
|
||||||
}
|
}
|
||||||
if Self.bufLength >= common.MAXIMUM_SEGMENT_SIZE*300 {
|
if Self.bufLength >= Self.calcThreshold {
|
||||||
Self.lastReadStart, Self.readStart = Self.readStart, time.Now()
|
Self.lastReadStart, Self.readStart = Self.readStart, time.Now()
|
||||||
Self.calcBandWidth()
|
Self.calcBandWidth()
|
||||||
}
|
}
|
||||||
@ -410,7 +442,21 @@ func (Self *bandwidth) SetCopySize(n uint16) {
|
|||||||
|
|
||||||
func (Self *bandwidth) calcBandWidth() {
|
func (Self *bandwidth) calcBandWidth() {
|
||||||
t := Self.readStart.Sub(Self.lastReadStart)
|
t := Self.readStart.Sub(Self.lastReadStart)
|
||||||
|
bufferSize, err := syscall.GetsockoptInt(int(Self.fd.Fd()), syscall.SOL_SOCKET, syscall.SO_RCVBUF)
|
||||||
|
//logs.Warn(bufferSize)
|
||||||
|
if err != nil {
|
||||||
|
logs.Warn(err)
|
||||||
|
Self.bufLength = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if Self.bufLength >= uint32(bufferSize) {
|
||||||
atomic.StoreUint64(&Self.readBandwidth, math.Float64bits(float64(Self.bufLength)/t.Seconds()))
|
atomic.StoreUint64(&Self.readBandwidth, math.Float64bits(float64(Self.bufLength)/t.Seconds()))
|
||||||
|
// calculate the hole socket buffer, the time meaning to fill the buffer
|
||||||
|
//logs.Warn(Self.Get())
|
||||||
|
} else {
|
||||||
|
Self.calcThreshold = uint32(bufferSize)
|
||||||
|
}
|
||||||
|
// socket buffer size is bigger than bufLength, so we don't calculate it
|
||||||
Self.bufLength = 0
|
Self.bufLength = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user