make sure all streams are tracked (#422)

* make sure all streams are tracked

* revert unnecesary change
This commit is contained in:
Dmitriy Ryajov 2020-11-04 21:52:54 -06:00 committed by GitHub
parent 6040cb4ef1
commit 3956f3fd69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 79 deletions

View File

@ -35,6 +35,8 @@ const
MaxWrites = 1024 ##\ MaxWrites = 1024 ##\
## Maximum number of in-flight writes - after this, we disconnect the peer ## Maximum number of in-flight writes - after this, we disconnect the peer
LPChannelTrackerName* = "LPChannel"
type type
LPChannel* = ref object of BufferStream LPChannel* = ref object of BufferStream
id*: uint64 # channel id id*: uint64 # channel id

View File

@ -20,6 +20,9 @@ export protocol
logScope: logScope:
topics = "secure" topics = "secure"
const
SecureConnTrackerName* = "SecureConn"
type type
Secure* = ref object of LPProtocol # base type for secure managers Secure* = ref object of LPProtocol # base type for secure managers

View File

@ -22,36 +22,7 @@ logScope:
topics = "bufferstream" topics = "bufferstream"
const const
BufferStreamTrackerName* = "libp2p.bufferstream" BufferStreamTrackerName* = "BufferStream"
type
BufferStreamTracker* = ref object of TrackerBase
opened*: uint64
closed*: uint64
proc setupBufferStreamTracker(): BufferStreamTracker {.gcsafe.}
proc getBufferStreamTracker(): BufferStreamTracker {.gcsafe.} =
result = cast[BufferStreamTracker](getTracker(BufferStreamTrackerName))
if isNil(result):
result = setupBufferStreamTracker()
proc dumpTracking(): string {.gcsafe.} =
var tracker = getBufferStreamTracker()
result = "Opened buffers: " & $tracker.opened & "\n" &
"Closed buffers: " & $tracker.closed
proc leakTransport(): bool {.gcsafe.} =
var tracker = getBufferStreamTracker()
result = (tracker.opened != tracker.closed)
proc setupBufferStreamTracker(): BufferStreamTracker =
result = new BufferStreamTracker
result.opened = 0
result.closed = 0
result.dump = dumpTracking
result.isLeaked = leakTransport
addTracker(BufferStreamTrackerName, result)
type type
BufferStream* = ref object of Connection BufferStream* = ref object of Connection
@ -79,7 +50,6 @@ method initStream*(s: BufferStream) =
s.readQueue = newAsyncQueue[seq[byte]](1) s.readQueue = newAsyncQueue[seq[byte]](1)
trace "BufferStream created", s trace "BufferStream created", s
inc getBufferStreamTracker().opened
proc newBufferStream*(timeout: Duration = DefaultConnectionTimeout): BufferStream = proc newBufferStream*(timeout: Duration = DefaultConnectionTimeout): BufferStream =
new result new result
@ -169,7 +139,6 @@ method closeImpl*(s: BufferStream): Future[void] =
if not s.pushedEof: # Potentially wake up reader if not s.pushedEof: # Potentially wake up reader
asyncSpawn s.pushEof() asyncSpawn s.pushEof()
inc getBufferStreamTracker().closed
trace "Closed BufferStream", s trace "Closed BufferStream", s
procCall Connection(s).closeImpl() # noraises, nocancels procCall Connection(s).closeImpl() # noraises, nocancels

View File

@ -16,6 +16,7 @@ logScope:
const const
DefaultChronosStreamTimeout = 10.minutes DefaultChronosStreamTimeout = 10.minutes
ChronosStreamTrackerName* = "ChronosStream"
type type
ChronosStream* = ref object of Connection ChronosStream* = ref object of Connection

View File

@ -19,7 +19,7 @@ logScope:
topics = "connection" topics = "connection"
const const
ConnectionTrackerName* = "libp2p.connection" ConnectionTrackerName* = "Connection"
DefaultConnectionTimeout* = 5.minutes DefaultConnectionTimeout* = 5.minutes
type type
@ -33,35 +33,8 @@ type
peerInfo*: PeerInfo peerInfo*: PeerInfo
observedAddr*: Multiaddress observedAddr*: Multiaddress
ConnectionTracker* = ref object of TrackerBase
opened*: uint64
closed*: uint64
proc setupConnectionTracker(): ConnectionTracker {.gcsafe.}
proc timeoutMonitor(s: Connection) {.async, gcsafe.} proc timeoutMonitor(s: Connection) {.async, gcsafe.}
proc getConnectionTracker*(): ConnectionTracker {.gcsafe.} =
result = cast[ConnectionTracker](getTracker(ConnectionTrackerName))
if isNil(result):
result = setupConnectionTracker()
proc dumpTracking(): string {.gcsafe.} =
var tracker = getConnectionTracker()
result = "Opened conns: " & $tracker.opened & "\n" &
"Closed conns: " & $tracker.closed
proc leakTransport(): bool {.gcsafe.} =
var tracker = getConnectionTracker()
result = (tracker.opened != tracker.closed)
proc setupConnectionTracker(): ConnectionTracker =
result = new ConnectionTracker
result.opened = 0
result.closed = 0
result.dump = dumpTracking
result.isLeaked = leakTransport
addTracker(ConnectionTrackerName, result)
func shortLog*(conn: Connection): string = func shortLog*(conn: Connection): string =
if conn.isNil: "Connection(nil)" if conn.isNil: "Connection(nil)"
elif conn.peerInfo.isNil: $conn.oid elif conn.peerInfo.isNil: $conn.oid
@ -85,15 +58,12 @@ method initStream*(s: Connection) =
trace "Idle timeout expired, closing connection", s trace "Idle timeout expired, closing connection", s
s.close() s.close()
inc getConnectionTracker().opened
method closeImpl*(s: Connection): Future[void] = method closeImpl*(s: Connection): Future[void] =
# Cleanup timeout timer # Cleanup timeout timer
trace "Closing connection", s trace "Closing connection", s
if not isNil(s.timerTaskFut) and not s.timerTaskFut.finished: if not isNil(s.timerTaskFut) and not s.timerTaskFut.finished:
s.timerTaskFut.cancel() s.timerTaskFut.cancel()
inc getConnectionTracker().closed
trace "Closed connection", s trace "Closed connection", s
procCall LPStream(s).closeImpl() procCall LPStream(s).closeImpl()

View File

@ -23,6 +23,9 @@ export oids
logScope: logScope:
topics = "lpstream" topics = "lpstream"
const
LPStreamTrackerName* = "LPStream"
type type
Direction* {.pure.} = enum Direction* {.pure.} = enum
In, Out In, Out
@ -49,6 +52,34 @@ type
InvalidVarintError* = object of LPStreamError InvalidVarintError* = object of LPStreamError
MaxSizeError* = object of LPStreamError MaxSizeError* = object of LPStreamError
StreamTracker* = ref object of TrackerBase
opened*: uint64
closed*: uint64
proc setupStreamTracker(name: string): StreamTracker =
let tracker = new StreamTracker
proc dumpTracking(): string {.gcsafe.} =
return "Opened " & tracker.id & " :" & $tracker.opened & "\n" &
"Closed " & tracker.id & " :" & $tracker.closed
proc leakTransport(): bool {.gcsafe.} =
return (tracker.opened != tracker.closed)
tracker.id = name
tracker.opened = 0
tracker.closed = 0
tracker.dump = dumpTracking
tracker.isLeaked = leakTransport
addTracker(name, tracker)
return tracker
proc getStreamTracker(name: string): StreamTracker {.gcsafe.} =
result = cast[StreamTracker](getTracker(name))
if isNil(result):
result = setupStreamTracker(name)
proc newLPStreamReadError*(p: ref CatchableError): ref CatchableError = proc newLPStreamReadError*(p: ref CatchableError): ref CatchableError =
var w = newException(LPStreamReadError, "Read stream failed") var w = newException(LPStreamReadError, "Read stream failed")
w.msg = w.msg & ", originated from [" & $p.name & "] " & p.msg w.msg = w.msg & ", originated from [" & $p.name & "] " & p.msg
@ -92,6 +123,7 @@ method initStream*(s: LPStream) {.base.} =
s.oid = genOid() s.oid = genOid()
libp2p_open_streams.inc(labelValues = [s.objName, $s.dir]) libp2p_open_streams.inc(labelValues = [s.objName, $s.dir])
inc getStreamTracker(s.objName).opened
trace "Stream created", s, objName = s.objName, dir = $s.dir trace "Stream created", s, objName = s.objName, dir = $s.dir
proc join*(s: LPStream): Future[void] = proc join*(s: LPStream): Future[void] =
@ -220,6 +252,7 @@ method closeImpl*(s: LPStream): Future[void] {.async, base.} =
trace "Closing stream", s, objName = s.objName, dir = $s.dir trace "Closing stream", s, objName = s.objName, dir = $s.dir
s.closeEvent.fire() s.closeEvent.fire()
libp2p_open_streams.dec(labelValues = [s.objName, $s.dir]) libp2p_open_streams.dec(labelValues = [s.objName, $s.dir])
inc getStreamTracker(s.objName).closed
trace "Closed stream", s, objName = s.objName, dir = $s.dir trace "Closed stream", s, objName = s.objName, dir = $s.dir
method close*(s: LPStream): Future[void] {.base, async.} = # {.raises [Defect].} method close*(s: LPStream): Future[void] {.base, async.} = # {.raises [Defect].}

View File

@ -6,13 +6,18 @@ import ../libp2p/transports/tcptransport
import ../libp2p/stream/bufferstream import ../libp2p/stream/bufferstream
import ../libp2p/crypto/crypto import ../libp2p/crypto/crypto
import ../libp2p/stream/lpstream import ../libp2p/stream/lpstream
import ../libp2p/muxers/mplex/lpchannel
import ../libp2p/protocols/secure/secure
const const
StreamTransportTrackerName = "stream.transport" StreamTransportTrackerName = "stream.transport"
StreamServerTrackerName = "stream.server" StreamServerTrackerName = "stream.server"
trackerNames = [ trackerNames = [
LPStreamTrackerName,
ConnectionTrackerName, ConnectionTrackerName,
LPChannelTrackerName,
SecureConnTrackerName,
BufferStreamTrackerName, BufferStreamTrackerName,
TcpTransportTrackerName, TcpTransportTrackerName,
StreamTransportTrackerName, StreamTransportTrackerName,

View File

@ -7,8 +7,8 @@ import ../libp2p/stream/bufferstream,
suite "BufferStream": suite "BufferStream":
teardown: teardown:
# echo getTracker("libp2p.bufferstream").dump() # echo getTracker(BufferStreamTrackerName).dump()
check getTracker("libp2p.bufferstream").isLeaked() == false check getTracker(BufferStreamTrackerName).isLeaked() == false
test "push data to buffer": test "push data to buffer":
proc testpushData(): Future[bool] {.async.} = proc testpushData(): Future[bool] {.async.} =

View File

@ -14,7 +14,9 @@ import ../libp2p/[errors,
peerinfo, peerinfo,
crypto/crypto, crypto/crypto,
protocols/protocol, protocols/protocol,
protocols/secure/secure,
muxers/muxer, muxers/muxer,
muxers/mplex/lpchannel,
stream/lpstream] stream/lpstream]
import ./helpers import ./helpers
@ -246,11 +248,12 @@ suite "Switch":
check not switch1.isConnected(switch2.peerInfo) check not switch1.isConnected(switch2.peerInfo)
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var channelTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo channelTracker.dump()
check bufferTracker.isLeaked() == false check channelTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
doAssert(not isNil(connTracker))
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false
@ -305,11 +308,11 @@ suite "Switch":
check not switch1.isConnected(switch2.peerInfo) check not switch1.isConnected(switch2.peerInfo)
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var bufferTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo bufferTracker.dump()
check bufferTracker.isLeaked() == false check bufferTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false
@ -370,11 +373,11 @@ suite "Switch":
check not switch1.isConnected(switch2.peerInfo) check not switch1.isConnected(switch2.peerInfo)
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var bufferTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo bufferTracker.dump()
check bufferTracker.isLeaked() == false check bufferTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false
@ -434,11 +437,11 @@ suite "Switch":
check not switch1.isConnected(switch2.peerInfo) check not switch1.isConnected(switch2.peerInfo)
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var bufferTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo bufferTracker.dump()
check bufferTracker.isLeaked() == false check bufferTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false
@ -498,11 +501,11 @@ suite "Switch":
check not switch1.isConnected(switch2.peerInfo) check not switch1.isConnected(switch2.peerInfo)
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var bufferTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo bufferTracker.dump()
check bufferTracker.isLeaked() == false check bufferTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false
@ -577,11 +580,11 @@ suite "Switch":
check not switch2.isConnected(switch1.peerInfo) check not switch2.isConnected(switch1.peerInfo)
check not switch3.isConnected(switch1.peerInfo) check not switch3.isConnected(switch1.peerInfo)
var bufferTracker = getTracker(BufferStreamTrackerName) var bufferTracker = getTracker(LPChannelTrackerName)
# echo bufferTracker.dump() # echo bufferTracker.dump()
check bufferTracker.isLeaked() == false check bufferTracker.isLeaked() == false
var connTracker = getTracker(ConnectionTrackerName) var connTracker = getTracker(SecureConnTrackerName)
# echo connTracker.dump() # echo connTracker.dump()
check connTracker.isLeaked() == false check connTracker.isLeaked() == false