don't crash on double peerinfo close (#167)
This commit is contained in:
parent
3053f03814
commit
618e01eba3
|
@ -13,9 +13,7 @@ import peerinfo,
|
||||||
errors,
|
errors,
|
||||||
multiaddress,
|
multiaddress,
|
||||||
stream/lpstream,
|
stream/lpstream,
|
||||||
peerinfo,
|
peerinfo
|
||||||
varint,
|
|
||||||
vbuffer
|
|
||||||
|
|
||||||
export lpstream
|
export lpstream
|
||||||
|
|
||||||
|
@ -64,18 +62,20 @@ proc setupConnectionTracker(): ConnectionTracker =
|
||||||
|
|
||||||
declareGauge libp2p_open_connection, "open Connection instances"
|
declareGauge libp2p_open_connection, "open Connection instances"
|
||||||
|
|
||||||
|
proc `$`*(conn: Connection): string =
|
||||||
|
if not isNil(conn.peerInfo):
|
||||||
|
result = $(conn.peerInfo)
|
||||||
|
|
||||||
proc bindStreamClose(conn: Connection) {.async.} =
|
proc bindStreamClose(conn: Connection) {.async.} =
|
||||||
# bind stream's close event to connection's close
|
# bind stream's close event to connection's close
|
||||||
# to ensure correct close propagation
|
# to ensure correct close propagation
|
||||||
if not isNil(conn.stream.closeEvent):
|
if not isNil(conn.stream.closeEvent):
|
||||||
await conn.stream.closeEvent.wait()
|
await conn.stream.closeEvent.wait()
|
||||||
trace "wrapped stream closed, about to close conn", closed = conn.isClosed,
|
trace "wrapped stream closed, about to close conn",
|
||||||
peer = if not isNil(conn.peerInfo):
|
closed = conn.isClosed, conn = $conn
|
||||||
conn.peerInfo.id else: ""
|
|
||||||
if not conn.isClosed:
|
if not conn.isClosed:
|
||||||
trace "wrapped stream closed, closing conn", closed = conn.isClosed,
|
trace "wrapped stream closed, closing conn",
|
||||||
peer = if not isNil(conn.peerInfo):
|
closed = conn.isClosed, conn = $conn
|
||||||
conn.peerInfo.id else: ""
|
|
||||||
await conn.close()
|
await conn.close()
|
||||||
|
|
||||||
proc init[T: Connection](self: var T, stream: LPStream): T =
|
proc init[T: Connection](self: var T, stream: LPStream): T =
|
||||||
|
@ -119,36 +119,26 @@ method closed*(s: Connection): bool =
|
||||||
result = s.stream.closed
|
result = s.stream.closed
|
||||||
|
|
||||||
method close*(s: Connection) {.async, gcsafe.} =
|
method close*(s: Connection) {.async, gcsafe.} =
|
||||||
trace "about to close connection", closed = s.closed,
|
trace "about to close connection", closed = s.closed, conn = $s
|
||||||
peer = if not isNil(s.peerInfo):
|
|
||||||
s.peerInfo.id else: ""
|
|
||||||
|
|
||||||
if not s.isClosed:
|
if not s.isClosed:
|
||||||
s.isClosed = true
|
s.isClosed = true
|
||||||
inc getConnectionTracker().closed
|
inc getConnectionTracker().closed
|
||||||
|
|
||||||
if not isNil(s.stream) and not s.stream.closed:
|
if not isNil(s.stream) and not s.stream.closed:
|
||||||
trace "closing child stream", closed = s.closed,
|
trace "closing child stream", closed = s.closed, conn = $s
|
||||||
peer = if not isNil(s.peerInfo):
|
|
||||||
s.peerInfo.id else: ""
|
|
||||||
await s.stream.close()
|
await s.stream.close()
|
||||||
|
|
||||||
s.closeEvent.fire()
|
s.closeEvent.fire()
|
||||||
|
|
||||||
trace "waiting readloops", count=s.readLoops.len
|
trace "waiting readloops", count=s.readLoops.len, conn = $s
|
||||||
let loopFuts = await allFinished(s.readLoops)
|
let loopFuts = await allFinished(s.readLoops)
|
||||||
checkFutures(loopFuts)
|
checkFutures(loopFuts)
|
||||||
s.readLoops = @[]
|
s.readLoops = @[]
|
||||||
|
|
||||||
trace "connection closed", closed = s.closed,
|
trace "connection closed", closed = s.closed, conn = $s
|
||||||
peer = if not isNil(s.peerInfo):
|
|
||||||
s.peerInfo.id else: ""
|
|
||||||
libp2p_open_connection.dec()
|
libp2p_open_connection.dec()
|
||||||
|
|
||||||
method getObservedAddrs*(c: Connection): Future[MultiAddress] {.base, async, gcsafe.} =
|
method getObservedAddrs*(c: Connection): Future[MultiAddress] {.base, async, gcsafe.} =
|
||||||
## get resolved multiaddresses for the connection
|
## get resolved multiaddresses for the connection
|
||||||
result = c.observedAddrs
|
result = c.observedAddrs
|
||||||
|
|
||||||
proc `$`*(conn: Connection): string =
|
|
||||||
if not isNil(conn.peerInfo):
|
|
||||||
result = $(conn.peerInfo)
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
import options
|
import options
|
||||||
import chronos
|
import chronos, chronicles
|
||||||
import peer, multiaddress, crypto/crypto
|
import peer, multiaddress, crypto/crypto
|
||||||
|
|
||||||
## A peer can be constructed in one of tree ways:
|
## A peer can be constructed in one of tree ways:
|
||||||
|
@ -35,6 +35,18 @@ type
|
||||||
of HasPublic:
|
of HasPublic:
|
||||||
key: Option[PublicKey]
|
key: Option[PublicKey]
|
||||||
|
|
||||||
|
proc id*(p: PeerInfo): string =
|
||||||
|
p.peerId.pretty()
|
||||||
|
|
||||||
|
proc `$`*(p: PeerInfo): string =
|
||||||
|
result.add(p.id)
|
||||||
|
|
||||||
|
result.add(" ")
|
||||||
|
result.add($p.addrs)
|
||||||
|
|
||||||
|
result.add(" ")
|
||||||
|
result.add($p.protocols)
|
||||||
|
|
||||||
template postInit(peerinfo: PeerInfo,
|
template postInit(peerinfo: PeerInfo,
|
||||||
addrs: openarray[MultiAddress],
|
addrs: openarray[MultiAddress],
|
||||||
protocols: openarray[string]) =
|
protocols: openarray[string]) =
|
||||||
|
@ -71,7 +83,11 @@ proc init*(p: typedesc[PeerInfo], key: PublicKey,
|
||||||
result.postInit(addrs, protocols)
|
result.postInit(addrs, protocols)
|
||||||
|
|
||||||
proc close*(p: PeerInfo) {.inline.} =
|
proc close*(p: PeerInfo) {.inline.} =
|
||||||
p.lifefut.complete()
|
if not p.lifefut.finished:
|
||||||
|
p.lifefut.complete()
|
||||||
|
else:
|
||||||
|
# TODO this should ideally not happen
|
||||||
|
notice "Closing closed peer", peer = p.id
|
||||||
|
|
||||||
proc join*(p: PeerInfo): Future[void] {.inline.} =
|
proc join*(p: PeerInfo): Future[void] {.inline.} =
|
||||||
var retFuture = newFuture[void]()
|
var retFuture = newFuture[void]()
|
||||||
|
@ -103,15 +119,3 @@ proc publicKey*(p: PeerInfo): Option[PublicKey] {.inline.} =
|
||||||
result = p.key
|
result = p.key
|
||||||
else:
|
else:
|
||||||
result = some(p.privateKey.getKey())
|
result = some(p.privateKey.getKey())
|
||||||
|
|
||||||
proc id*(p: PeerInfo): string {.inline.} =
|
|
||||||
p.peerId.pretty()
|
|
||||||
|
|
||||||
proc `$`*(p: PeerInfo): string =
|
|
||||||
result.add(p.id)
|
|
||||||
|
|
||||||
result.add(" ")
|
|
||||||
result.add($p.addrs)
|
|
||||||
|
|
||||||
result.add(" ")
|
|
||||||
result.add($p.protocols)
|
|
||||||
|
|
Loading…
Reference in New Issue