mirror of
https://github.com/vacp2p/nim-libp2p.git
synced 2025-02-11 07:57:37 +00:00
* use stream directly in chronosstream for now, chronos.AsyncStream is not used to provide any features on top of chronos.Stream, so in order to simplify the code, chronosstream can be used directly. In particular, the exception handling is broken in the current chronosstream - opening and closing the stream is simplified this way as well. A future implementation that actually takes advantage of the AsyncStream features would wrap AsyncStream instead as a separate lpstream implementation, leaving this one as-is. * work around chronos exception type issue
73 lines
2.1 KiB
Nim
73 lines
2.1 KiB
Nim
## Nim-LibP2P
|
|
## Copyright (c) 2019 Status Research & Development GmbH
|
|
## Licensed under either of
|
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
## at your option.
|
|
## This file may not be copied, modified, or distributed except according to
|
|
## those terms.
|
|
|
|
import chronos, chronicles
|
|
import lpstream, ../utility
|
|
|
|
logScope:
|
|
topic = "ChronosStream"
|
|
|
|
type ChronosStream* = ref object of LPStream
|
|
client: StreamTransport
|
|
|
|
proc newChronosStream*(client: StreamTransport): ChronosStream =
|
|
new result
|
|
result.client = client
|
|
result.closeEvent = newAsyncEvent()
|
|
|
|
template withExceptions(body: untyped) =
|
|
try:
|
|
body
|
|
except TransportIncompleteError:
|
|
raise newLPStreamIncompleteError()
|
|
except TransportLimitError:
|
|
raise newLPStreamLimitError()
|
|
except TransportUseClosedError:
|
|
raise newLPStreamEOFError()
|
|
except TransportError:
|
|
# TODO https://github.com/status-im/nim-chronos/pull/99
|
|
raise newLPStreamEOFError()
|
|
# raise (ref LPStreamError)(msg: exc.msg, parent: exc)
|
|
|
|
method readExactly*(s: ChronosStream,
|
|
pbytes: pointer,
|
|
nbytes: int): Future[void] {.async.} =
|
|
if s.client.atEof:
|
|
raise newLPStreamEOFError()
|
|
|
|
withExceptions:
|
|
await s.client.readExactly(pbytes, nbytes)
|
|
|
|
method readOnce*(s: ChronosStream, pbytes: pointer, nbytes: int): Future[int] {.async.} =
|
|
if s.client.atEof:
|
|
raise newLPStreamEOFError()
|
|
|
|
withExceptions:
|
|
result = await s.client.readOnce(pbytes, nbytes)
|
|
|
|
method write*(s: ChronosStream, msg: seq[byte]) {.async.} =
|
|
if msg.len == 0:
|
|
return
|
|
|
|
withExceptions:
|
|
# Returns 0 sometimes when write fails - but there's not much we can do here?
|
|
if (await s.client.write(msg)) != msg.len:
|
|
raise (ref LPStreamError)(msg: "Write couldn't finish writing")
|
|
|
|
method closed*(s: ChronosStream): bool {.inline.} =
|
|
result = s.client.closed
|
|
|
|
method close*(s: ChronosStream) {.async.} =
|
|
if not s.closed:
|
|
trace "shutting chronos stream", address = $s.client.remoteAddress()
|
|
if not s.client.closed():
|
|
await s.client.closeWait()
|
|
|
|
s.closeEvent.fire()
|