change slide window bandwidth calculation

This commit is contained in:
ffdfgdfg 2019-10-13 22:45:40 +08:00
parent 1f8e441090
commit f5d5f63366
4 changed files with 163 additions and 84 deletions

View File

@ -65,8 +65,9 @@ func (Self *BasePackager) Pack(writer io.Writer) (err error) {
//Unpack 会导致传入的数字类型转化成float64 //Unpack 会导致传入的数字类型转化成float64
//主要原因是json unmarshal并未传入正确的数据类型 //主要原因是json unmarshal并未传入正确的数据类型
func (Self *BasePackager) UnPack(reader io.Reader) (err error) { func (Self *BasePackager) UnPack(reader io.Reader) (n uint16, err error) {
Self.clean() Self.clean()
n += 2 // uint16
err = binary.Read(reader, binary.LittleEndian, &Self.Length) err = binary.Read(reader, binary.LittleEndian, &Self.Length)
if err != nil { if err != nil {
return return
@ -80,6 +81,7 @@ func (Self *BasePackager) UnPack(reader io.Reader) (err error) {
// err = io.ErrUnexpectedEOF // err = io.ErrUnexpectedEOF
//} //}
err = binary.Read(reader, binary.LittleEndian, Self.Content) err = binary.Read(reader, binary.LittleEndian, Self.Content)
n += Self.Length
return return
} }
@ -137,12 +139,13 @@ func (Self *ConnPackager) Pack(writer io.Writer) (err error) {
return return
} }
func (Self *ConnPackager) UnPack(reader io.Reader) (err error) { func (Self *ConnPackager) UnPack(reader io.Reader) (n uint16, err error) {
err = binary.Read(reader, binary.LittleEndian, &Self.ConnType) err = binary.Read(reader, binary.LittleEndian, &Self.ConnType)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return return
} }
err = Self.BasePackager.UnPack(reader) n, err = Self.BasePackager.UnPack(reader)
n += 2
return return
} }
@ -203,7 +206,7 @@ func (Self *MuxPackager) Pack(writer io.Writer) (err error) {
return return
} }
func (Self *MuxPackager) UnPack(reader io.Reader) (err error) { func (Self *MuxPackager) UnPack(reader io.Reader) (n uint16, err error) {
err = binary.Read(reader, binary.LittleEndian, &Self.Flag) err = binary.Read(reader, binary.LittleEndian, &Self.Flag)
if err != nil { if err != nil {
return return
@ -216,14 +219,17 @@ func (Self *MuxPackager) UnPack(reader io.Reader) (err error) {
case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN: case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN:
Self.Content = WindowBuff.Get() // need get a window buf from pool Self.Content = WindowBuff.Get() // need get a window buf from pool
Self.BasePackager.clean() // also clean the content Self.BasePackager.clean() // also clean the content
err = Self.BasePackager.UnPack(reader) n, err = Self.BasePackager.UnPack(reader)
//logs.Warn("unpack", Self.Length, string(Self.Content)) //logs.Warn("unpack", Self.Length, string(Self.Content))
case MUX_MSG_SEND_OK: case MUX_MSG_SEND_OK:
err = binary.Read(reader, binary.LittleEndian, &Self.Window) err = binary.Read(reader, binary.LittleEndian, &Self.Window)
if err != nil { if err != nil {
return return
} }
n += 4 // uint32
err = binary.Read(reader, binary.LittleEndian, &Self.ReadLength) err = binary.Read(reader, binary.LittleEndian, &Self.ReadLength)
n += 4 // uint32
} }
n += 5 //uint8 int32
return return
} }

View File

@ -3,7 +3,6 @@ package mux
import ( import (
"errors" "errors"
"io" "io"
"math"
"net" "net"
"sync" "sync"
"time" "time"
@ -137,8 +136,8 @@ type ReceiveWindow struct {
readWait bool readWait bool
windowFull bool windowFull bool
count int8 count int8
bw *bandwidth //bw *bandwidth
once sync.Once once sync.Once
window window
} }
@ -146,7 +145,7 @@ func (Self *ReceiveWindow) New(mux *Mux) {
// initial a window for receive // initial a window for receive
Self.readOp = make(chan struct{}) Self.readOp = make(chan struct{})
Self.bufQueue.New() Self.bufQueue.New()
Self.bw = new(bandwidth) //Self.bw = new(bandwidth)
Self.element = new(ListElement) Self.element = new(ListElement)
Self.maxSize = 8192 Self.maxSize = 8192
Self.mux = mux Self.mux = mux
@ -175,7 +174,7 @@ func (Self *ReceiveWindow) CalcSize() {
// calculating maximum receive window size // calculating maximum receive window size
if Self.count == 0 { if Self.count == 0 {
//logs.Warn("ping, bw", Self.mux.latency, Self.bw.Get()) //logs.Warn("ping, bw", Self.mux.latency, Self.bw.Get())
n := uint32(2 * Self.mux.latency * Self.bw.Get()) n := uint32(2 * Self.mux.latency * Self.mux.bw.Get() * 1.5 / float64(Self.mux.connMap.Size()))
if n < 8192 { if n < 8192 {
n = 8192 n = 8192
} }
@ -183,13 +182,16 @@ func (Self *ReceiveWindow) CalcSize() {
n = Self.bufQueue.Len() n = Self.bufQueue.Len()
} }
// set the minimal size // set the minimal size
if n > 2*Self.maxSize {
n = 2 * Self.maxSize
}
if n > common.MAXIMUM_WINDOW_SIZE { if n > common.MAXIMUM_WINDOW_SIZE {
n = common.MAXIMUM_WINDOW_SIZE n = common.MAXIMUM_WINDOW_SIZE
} }
// set the maximum size // set the maximum size
//logs.Warn("n", n) //logs.Warn("n", n)
Self.maxSize = n Self.maxSize = n
Self.count = -5 Self.count = -10
} }
Self.count += 1 Self.count += 1
} }
@ -225,7 +227,7 @@ func (Self *ReceiveWindow) Read(p []byte, id int32) (n int, err error) {
l := 0 l := 0
//logs.Warn("receive window read off, element.l", Self.off, Self.element.l) //logs.Warn("receive window read off, element.l", Self.off, Self.element.l)
copyData: copyData:
Self.bw.StartRead() //Self.bw.StartRead()
if Self.off == uint32(Self.element.l) { if Self.off == uint32(Self.element.l) {
// on the first Read method invoked, Self.off and Self.element.l // on the first Read method invoked, Self.off and Self.element.l
// both zero value // both zero value
@ -241,7 +243,7 @@ copyData:
//logs.Warn("pop element", Self.element.l, Self.element.part) //logs.Warn("pop element", Self.element.l, Self.element.part)
} }
l = copy(p[pOff:], Self.element.buf[Self.off:]) l = copy(p[pOff:], Self.element.buf[Self.off:])
Self.bw.SetCopySize(l) //Self.bw.SetCopySize(l)
pOff += l pOff += l
Self.off += uint32(l) Self.off += uint32(l)
Self.bufQueue.mutex.Lock() Self.bufQueue.mutex.Lock()
@ -250,7 +252,7 @@ copyData:
Self.bufQueue.mutex.Unlock() Self.bufQueue.mutex.Unlock()
n += l n += l
l = 0 l = 0
Self.bw.EndRead() //Self.bw.EndRead()
Self.sendStatus(id) Self.sendStatus(id)
if Self.off == uint32(Self.element.l) { if Self.off == uint32(Self.element.l) {
//logs.Warn("put the element end ", string(Self.element.buf[:15])) //logs.Warn("put the element end ", string(Self.element.buf[:15]))
@ -469,65 +471,81 @@ func (Self *SendWindow) SetTimeOut(t time.Time) {
Self.timeout = t Self.timeout = t
} }
type bandwidth struct { //type bandwidth struct {
lastReadStart time.Time // readStart time.Time
readStart time.Time // lastReadStart time.Time
readEnd time.Time // readEnd time.Time
bufLength int // lastReadEnd time.Time
lastBufLength int // bufLength int
count int8 // lastBufLength int
readBW float64 // count int8
writeBW float64 // readBW float64
} // writeBW float64
// readBandwidth float64
func (Self *bandwidth) StartRead() { //}
Self.lastReadStart, Self.readStart = Self.readStart, time.Now() //
} //func (Self *bandwidth) StartRead() {
// Self.lastReadStart, Self.readStart = Self.readStart, time.Now()
func (Self *bandwidth) EndRead() { // if !Self.lastReadStart.IsZero() {
if !Self.lastReadStart.IsZero() { // if Self.count == -5 {
if Self.count == 0 { // Self.calcBandWidth()
Self.calcWriteBandwidth() // }
} // }
} //}
Self.readEnd = time.Now() //
if Self.count == 0 { //func (Self *bandwidth) EndRead() {
Self.calcReadBandwidth() // Self.lastReadEnd, Self.readEnd = Self.readEnd, time.Now()
Self.count = -3 // if Self.count == -5 {
} // Self.calcWriteBandwidth()
Self.count += 1 // }
} // if Self.count == 0 {
// Self.calcReadBandwidth()
func (Self *bandwidth) SetCopySize(n int) { // Self.count = -6
// must be invoke between StartRead and EndRead // }
Self.lastBufLength, Self.bufLength = Self.bufLength, n // Self.count += 1
} //}
//
func (Self *bandwidth) calcReadBandwidth() { //func (Self *bandwidth) SetCopySize(n int) {
// Bandwidth between nps and npc // // must be invoke between StartRead and EndRead
readTime := Self.readEnd.Sub(Self.readStart) // Self.lastBufLength, Self.bufLength = Self.bufLength, n
Self.readBW = float64(Self.bufLength) / readTime.Seconds() //}
//logs.Warn("calc read bw", Self.bufLength, readTime.Seconds()) //// calculating
} //// start end start end
//// read read
func (Self *bandwidth) calcWriteBandwidth() { //// write
// Bandwidth between nps and user, npc and application //
//logs.Warn("calc write bw") //func (Self *bandwidth) calcBandWidth() {
writeTime := Self.readEnd.Sub(Self.lastReadStart) // t := Self.readStart.Sub(Self.lastReadStart)
Self.writeBW = float64(Self.lastBufLength) / writeTime.Seconds() // if Self.lastBufLength >= 32768 {
} // Self.readBandwidth = float64(Self.lastBufLength) / t.Seconds()
// }
func (Self *bandwidth) Get() (bw float64) { //}
// The zero value, 0 for numeric types //
if Self.writeBW == 0 && Self.readBW == 0 { //func (Self *bandwidth) calcReadBandwidth() {
//logs.Warn("bw both 0") // // Bandwidth between nps and npc
return 100 // readTime := Self.readEnd.Sub(Self.readStart)
} // Self.readBW = float64(Self.bufLength) / readTime.Seconds()
if Self.writeBW == 0 && Self.readBW != 0 { // //logs.Warn("calc read bw", Self.readBW, Self.bufLength, readTime.Seconds())
return Self.readBW //}
} //
if Self.readBW == 0 && Self.writeBW != 0 { //func (Self *bandwidth) calcWriteBandwidth() {
return Self.writeBW // // Bandwidth between nps and user, npc and application
} // writeTime := Self.readStart.Sub(Self.lastReadEnd)
return math.Min(Self.readBW, Self.writeBW) // Self.writeBW = float64(Self.lastBufLength) / writeTime.Seconds()
} // //logs.Warn("calc write bw", Self.writeBW, Self.bufLength, writeTime.Seconds())
//}
//
//func (Self *bandwidth) Get() (bw float64) {
// // The zero value, 0 for numeric types
// if Self.writeBW == 0 && Self.readBW == 0 {
// //logs.Warn("bw both 0")
// return 100
// }
// if Self.writeBW == 0 && Self.readBW != 0 {
// return Self.readBW
// }
// if Self.readBW == 0 && Self.writeBW != 0 {
// return Self.writeBW
// }
// return Self.readBandwidth
//}

View File

@ -20,6 +20,10 @@ func NewConnMap() *connMap {
return connMap return connMap
} }
func (s *connMap) Size() (n int) {
return len(s.connMap)
}
func (s *connMap) Get(id int32) (*conn, bool) { func (s *connMap) Get(id int32) (*conn, bool) {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()

View File

@ -24,6 +24,7 @@ type Mux struct {
IsClose bool IsClose bool
pingOk int pingOk int
latency float64 latency float64
bw *bandwidth
pingCh chan []byte pingCh chan []byte
pingTimer *time.Timer pingTimer *time.Timer
connType string connType string
@ -37,8 +38,9 @@ func NewMux(c net.Conn, connType string) *Mux {
conn: c, conn: c,
connMap: NewConnMap(), connMap: NewConnMap(),
id: 0, id: 0,
closeChan: make(chan struct{}), closeChan: make(chan struct{}, 3),
newConnCh: make(chan *conn), newConnCh: make(chan *conn),
bw: new(bandwidth),
IsClose: false, IsClose: false,
connType: connType, connType: connType,
bufCh: make(chan *bytes.Buffer), bufCh: make(chan *bytes.Buffer),
@ -91,6 +93,9 @@ func (s *Mux) Addr() net.Addr {
} }
func (s *Mux) sendInfo(flag uint8, id int32, data ...interface{}) { func (s *Mux) sendInfo(flag uint8, id int32, data ...interface{}) {
if s.IsClose {
return
}
var err error var err error
pack := common.MuxPack.Get() pack := common.MuxPack.Get()
err = pack.NewPac(flag, id, data...) err = pack.NewPac(flag, id, data...)
@ -160,6 +165,9 @@ func (s *Mux) ping() {
for { for {
if s.IsClose { if s.IsClose {
ticker.Stop() ticker.Stop()
if !s.pingTimer.Stop() {
<-s.pingTimer.C
}
break break
} }
select { select {
@ -189,6 +197,9 @@ func (s *Mux) pingReturn() {
var now time.Time var now time.Time
var data []byte var data []byte
for { for {
if s.IsClose {
break
}
select { select {
case data = <-s.pingCh: case data = <-s.pingCh:
case <-s.closeChan: case <-s.closeChan:
@ -199,12 +210,12 @@ func (s *Mux) pingReturn() {
break break
} }
_ = now.UnmarshalText(data) _ = now.UnmarshalText(data)
s.latency = time.Now().UTC().Sub(now).Seconds() / 2 latency := time.Now().UTC().Sub(now).Seconds() / 2
logs.Warn("latency", s.latency) if latency < 0.5 && latency > 0 {
common.WindowBuff.Put(data) s.latency = latency
if s.latency <= 0 {
logs.Warn("latency err", s.latency)
} }
//logs.Warn("latency", s.latency)
common.WindowBuff.Put(data)
} }
}() }()
} }
@ -212,14 +223,18 @@ func (s *Mux) pingReturn() {
func (s *Mux) readSession() { func (s *Mux) readSession() {
go func() { go func() {
pack := common.MuxPack.Get() pack := common.MuxPack.Get()
var l uint16
var err error
for { for {
if s.IsClose { if s.IsClose {
break break
} }
pack = common.MuxPack.Get() pack = common.MuxPack.Get()
if pack.UnPack(s.conn) != nil { s.bw.StartRead()
if l, err = pack.UnPack(s.conn); err != nil {
break break
} }
s.bw.SetCopySize(l)
s.pingOk = 0 s.pingOk = 0
switch pack.Flag { switch pack.Flag {
case common.MUX_NEW_CONN: //new connection case common.MUX_NEW_CONN: //new connection
@ -239,7 +254,7 @@ func (s *Mux) readSession() {
if connection, ok := s.connMap.Get(pack.Id); ok && !connection.isClose { if connection, ok := s.connMap.Get(pack.Id); ok && !connection.isClose {
switch pack.Flag { switch pack.Flag {
case common.MUX_NEW_MSG, common.MUX_NEW_MSG_PART: //new msg from remote connection case common.MUX_NEW_MSG, common.MUX_NEW_MSG_PART: //new msg from remote connection
err := s.newMsg(connection, pack) err = s.newMsg(connection, pack)
if err != nil { if err != nil {
connection.Close() connection.Close()
} }
@ -299,6 +314,7 @@ func (s *Mux) Close() error {
s.connMap.Close() s.connMap.Close()
s.closeChan <- struct{}{} s.closeChan <- struct{}{}
s.closeChan <- struct{}{} s.closeChan <- struct{}{}
s.closeChan <- struct{}{}
close(s.newConnCh) close(s.newConnCh)
return s.conn.Close() return s.conn.Close()
} }
@ -311,3 +327,38 @@ func (s *Mux) getId() (id int32) {
} }
return return
} }
type bandwidth struct {
readStart time.Time
lastReadStart time.Time
bufLength uint16
readBandwidth float64
}
func (Self *bandwidth) StartRead() {
if Self.readStart.IsZero() {
Self.readStart = time.Now()
}
if Self.bufLength >= 16384 {
Self.lastReadStart, Self.readStart = Self.readStart, time.Now()
Self.calcBandWidth()
}
}
func (Self *bandwidth) SetCopySize(n uint16) {
Self.bufLength += n
}
func (Self *bandwidth) calcBandWidth() {
t := Self.readStart.Sub(Self.lastReadStart)
Self.readBandwidth = float64(Self.bufLength) / t.Seconds()
Self.bufLength = 0
}
func (Self *bandwidth) Get() (bw float64) {
// The zero value, 0 for numeric types
if Self.readBandwidth <= 0 {
Self.readBandwidth = 100
}
return Self.readBandwidth
}