proper server startup sequence

This commit is contained in:
Dmitriy Ryajov 2019-09-11 18:15:04 -06:00
parent 5f2d944545
commit 4d9444afe9
3 changed files with 21 additions and 14 deletions

View File

@ -184,18 +184,21 @@ proc mount*[T: LPProtocol](s: Switch, proto: T) {.gcsafe.} =
s.ms.addHandler(proto.codec, proto) s.ms.addHandler(proto.codec, proto)
proc start*(s: Switch) {.async.} = proc start*(s: Switch): Future[seq[Future[void]]] {.async.} =
proc handle(conn: Connection): Future[void] {.async, closure, gcsafe.} = proc handle(conn: Connection): Future[void] {.async, closure, gcsafe.} =
try: try:
if (await s.ms.select(conn)): if (await s.ms.select(conn)): # just handshake
await s.ms.handle(conn) # handle incoming connection await s.ms.handle(conn) # handle incoming connection
except: except:
await s.cleanupConn(conn) await s.cleanupConn(conn)
var startFuts: seq[Future[void]]
for t in s.transports: # for each transport for t in s.transports: # for each transport
for a in s.peerInfo.addrs: for a in s.peerInfo.addrs:
if t.handles(a): # check if it handles the multiaddr if t.handles(a): # check if it handles the multiaddr
await t.listen(a, handle) # listen for incoming connections var server = await t.listen(a, handle)
startFuts.add(server)
result = startFuts # listen for incoming connections
proc stop*(s: Switch) {.async.} = proc stop*(s: Switch) {.async.} =
await allFutures(s.transports.mapIt(it.close())) await allFutures(s.transports.mapIt(it.close()))

View File

@ -7,11 +7,14 @@
## This file may not be copied, modified, or distributed except according to ## This file may not be copied, modified, or distributed except according to
## those terms. ## those terms.
import chronos import chronos, chronicles
import transport, ../wire, ../connection, import transport, ../wire, ../connection,
../multiaddress, ../connection, ../multiaddress, ../connection,
../multicodec, ../stream/chronosstream ../multicodec, ../stream/chronosstream
logScope:
topic = "TcpTransport"
type TcpTransport* = ref object of Transport type TcpTransport* = ref object of Transport
server*: StreamServer server*: StreamServer
@ -20,6 +23,7 @@ proc connHandler*(t: Transport,
client: StreamTransport, client: StreamTransport,
initiator: bool = false): initiator: bool = false):
Future[Connection] {.async, gcsafe.} = Future[Connection] {.async, gcsafe.} =
debug "handling connection for", address = $client.remoteAddress
let conn: Connection = newConnection(newChronosStream(server, client)) let conn: Connection = newConnection(newChronosStream(server, client))
if not initiator: if not initiator:
let handlerFut = if t.handler == nil: nil else: t.handler(conn) let handlerFut = if t.handler == nil: nil else: t.handler(conn)
@ -30,6 +34,7 @@ proc connHandler*(t: Transport,
proc connCb(server: StreamServer, proc connCb(server: StreamServer,
client: StreamTransport) {.async, gcsafe.} = client: StreamTransport) {.async, gcsafe.} =
debug "incomming connection for", address = $client.remoteAddress
let t: Transport = cast[Transport](server.udata) let t: Transport = cast[Transport](server.udata)
discard t.connHandler(server, client) discard t.connHandler(server, client)
@ -38,6 +43,7 @@ method init*(t: TcpTransport) =
method close*(t: TcpTransport): Future[void] {.async, gcsafe.} = method close*(t: TcpTransport): Future[void] {.async, gcsafe.} =
## start the transport ## start the transport
debug "stopping transport"
await procCall Transport(t).close() # call base await procCall Transport(t).close() # call base
t.server.stop() t.server.stop()
@ -46,21 +52,18 @@ method close*(t: TcpTransport): Future[void] {.async, gcsafe.} =
method listen*(t: TcpTransport, method listen*(t: TcpTransport,
ma: MultiAddress, ma: MultiAddress,
handler: ConnHandler): handler: ConnHandler):
Future[void] {.async, gcsafe.} = Future[Future[void]] {.async, gcsafe.} =
await procCall Transport(t).listen(ma, handler) # call base discard await procCall Transport(t).listen(ma, handler) # call base
## listen on the transport ## listen on the transport
let listenFuture: Future[void] = newFuture[void]() t.server = createStreamServer(t.ma, connCb, {}, t)
result = listenFuture t.server.start()
result = t.server.join()
let server = createStreamServer(t.ma, connCb, {}, t)
t.server = server
server.start()
listenFuture.complete()
method dial*(t: TcpTransport, method dial*(t: TcpTransport,
address: MultiAddress): address: MultiAddress):
Future[Connection] {.async, gcsafe.} = Future[Connection] {.async, gcsafe.} =
debug "dialing remote peer", address = $address
## dial a peer ## dial a peer
let client: StreamTransport = await connect(address) let client: StreamTransport = await connect(address)
result = await t.connHandler(t.server, client, true) result = await t.connHandler(t.server, client, true)

View File

@ -40,7 +40,8 @@ method close*(t: Transport) {.base, async, gcsafe.} =
method listen*(t: Transport, method listen*(t: Transport,
ma: MultiAddress, ma: MultiAddress,
handler: ConnHandler) {.base, async, gcsafe.} = handler: ConnHandler):
Future[Future[void]] {.base, async, gcsafe.} =
## listen for incoming connections ## listen for incoming connections
t.ma = ma t.ma = ma
t.handler = handler t.handler = handler