mirror of
https://github.com/vacp2p/nim-libp2p-experimental.git
synced 2025-01-28 19:15:59 +00:00
Yamux automatic window scaling
This commit is contained in:
parent
8d5ea43e2b
commit
c8bb598e66
@ -146,6 +146,7 @@ type
|
|||||||
recvWindow: int
|
recvWindow: int
|
||||||
sendWindow: int
|
sendWindow: int
|
||||||
maxRecvWindow: int
|
maxRecvWindow: int
|
||||||
|
automaticWindowScaling: bool
|
||||||
conn: Connection
|
conn: Connection
|
||||||
isSrc: bool
|
isSrc: bool
|
||||||
opened: bool
|
opened: bool
|
||||||
@ -232,6 +233,10 @@ proc updateRecvWindow(channel: YamuxChannel) {.async.} =
|
|||||||
))
|
))
|
||||||
trace "increasing the recvWindow", delta
|
trace "increasing the recvWindow", delta
|
||||||
|
|
||||||
|
proc setMaxRecvWindow*(channel: YamuxChannel, maxRecvWindow: int) =
|
||||||
|
channel.automaticWindowScaling = false
|
||||||
|
channel.maxRecvWindow = maxRecvWindow
|
||||||
|
|
||||||
method readOnce*(
|
method readOnce*(
|
||||||
channel: YamuxChannel,
|
channel: YamuxChannel,
|
||||||
pbytes: pointer,
|
pbytes: pointer,
|
||||||
@ -247,6 +252,7 @@ method readOnce*(
|
|||||||
newLPStreamConnDownError()
|
newLPStreamConnDownError()
|
||||||
if channel.returnedEof:
|
if channel.returnedEof:
|
||||||
raise newLPStreamRemoteClosedError()
|
raise newLPStreamRemoteClosedError()
|
||||||
|
|
||||||
if channel.recvQueue.len == 0:
|
if channel.recvQueue.len == 0:
|
||||||
channel.receivedData.clear()
|
channel.receivedData.clear()
|
||||||
await channel.closedRemotely or channel.receivedData.wait()
|
await channel.closedRemotely or channel.receivedData.wait()
|
||||||
@ -260,6 +266,9 @@ method readOnce*(
|
|||||||
toOpenArray(p, 0, nbytes - 1)[0..<toRead] = channel.recvQueue.toOpenArray(0, toRead - 1)
|
toOpenArray(p, 0, nbytes - 1)[0..<toRead] = channel.recvQueue.toOpenArray(0, toRead - 1)
|
||||||
channel.recvQueue = channel.recvQueue[toRead..^1]
|
channel.recvQueue = channel.recvQueue[toRead..^1]
|
||||||
|
|
||||||
|
if nbytes > channel.maxRecvWindow and channel.automaticWindowScaling:
|
||||||
|
channel.maxRecvWindow = nbytes
|
||||||
|
|
||||||
# We made some room in the recv buffer let the peer know
|
# We made some room in the recv buffer let the peer know
|
||||||
await channel.updateRecvWindow()
|
await channel.updateRecvWindow()
|
||||||
channel.activity = true
|
channel.activity = true
|
||||||
@ -273,9 +282,6 @@ proc gotDataFromRemote(channel: YamuxChannel, b: seq[byte]) {.async.} =
|
|||||||
libp2p_yamux_recv_queue.observe(channel.recvQueue.len.int64)
|
libp2p_yamux_recv_queue.observe(channel.recvQueue.len.int64)
|
||||||
await channel.updateRecvWindow()
|
await channel.updateRecvWindow()
|
||||||
|
|
||||||
proc setMaxRecvWindow*(channel: YamuxChannel, maxRecvWindow: int) =
|
|
||||||
channel.maxRecvWindow = maxRecvWindow
|
|
||||||
|
|
||||||
proc trySend(channel: YamuxChannel) {.async.} =
|
proc trySend(channel: YamuxChannel) {.async.} =
|
||||||
if channel.isSending:
|
if channel.isSending:
|
||||||
return
|
return
|
||||||
@ -384,6 +390,7 @@ proc createStream(m: Yamux, id: uint32, isSrc: bool): YamuxChannel =
|
|||||||
maxRecvWindow: DefaultWindowSize,
|
maxRecvWindow: DefaultWindowSize,
|
||||||
recvWindow: DefaultWindowSize,
|
recvWindow: DefaultWindowSize,
|
||||||
sendWindow: DefaultWindowSize,
|
sendWindow: DefaultWindowSize,
|
||||||
|
automaticWindowScaling: true,
|
||||||
isSrc: isSrc,
|
isSrc: isSrc,
|
||||||
conn: m.connection,
|
conn: m.connection,
|
||||||
receivedData: newAsyncEvent(),
|
receivedData: newAsyncEvent(),
|
||||||
|
@ -134,6 +134,27 @@ suite "Yamux":
|
|||||||
# 1 for initial exhaustion + (142 / 20) = 9
|
# 1 for initial exhaustion + (142 / 20) = 9
|
||||||
check numberOfRead == 9
|
check numberOfRead == 9
|
||||||
|
|
||||||
|
asyncTest "Automatic window size":
|
||||||
|
mSetup()
|
||||||
|
|
||||||
|
let writerBlocker = newFuture[void]()
|
||||||
|
var numberOfRead = 0
|
||||||
|
yamuxb.streamHandler = proc(conn: Connection) {.async.} =
|
||||||
|
var buffer: array[512000, byte]
|
||||||
|
while (await conn.readOnce(addr buffer[0], 512000)) > 0:
|
||||||
|
numberOfRead.inc()
|
||||||
|
writerBlocker.complete()
|
||||||
|
await conn.close()
|
||||||
|
let streamA = await yamuxa.newStream()
|
||||||
|
# Need to exhaust initial window first
|
||||||
|
await wait(streamA.write(newSeq[byte](256000)), 1.seconds) # shouldn't block
|
||||||
|
await streamA.write(newSeq[byte](256000 * 5))
|
||||||
|
await streamA.close()
|
||||||
|
|
||||||
|
await writerBlocker
|
||||||
|
|
||||||
|
check numberOfRead == 4
|
||||||
|
|
||||||
asyncTest "Saturate until reset":
|
asyncTest "Saturate until reset":
|
||||||
mSetup()
|
mSetup()
|
||||||
let writerBlocker = newFuture[void]()
|
let writerBlocker = newFuture[void]()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user