mirror of
https://github.com/ehang-io/nps.git
synced 2025-07-03 04:53:50 +00:00
change slide window bandwidth calculation
This commit is contained in:
parent
1f8e441090
commit
f5d5f63366
@ -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
|
||||||
}
|
}
|
||||||
|
160
lib/mux/conn.go
160
lib/mux/conn.go
@ -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
|
||||||
|
//}
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user