Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Questionable #35

Merged
merged 1 commit into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion quic.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ requires "nimcrypto >= 0.5.4 & < 0.6.0"
requires "ngtcp2 >= 0.32.0 & < 0.33.0"
requires "upraises >= 0.1.0 & < 0.2.0"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is another dep we don't use in low-level libs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For upraises, I would argue we won't need it in a few months anyway (after 1.6 migration), so it might be easier to just remove it then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be a search/replace operation, no? with the new when (NimMajor, NimMinor) < (1, 4): ... else: ... style, we get rid of the warning and we don't have to use weird/unusual constructs

also, for low-level libs we might want to keep 1.2-compat longer than end-user apps (no point breaking things that work)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requires "asynctest >= 0.3.0 & < 0.4.0"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, this is covered by chronos asyncTest

requires "questionable >= 0.10.0 & < 0.11.0"
requires "unittest2 >= 0.0.4 & < 0.1.0"
10 changes: 8 additions & 2 deletions quic/basics.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import pkg/chronos
import pkg/questionable
import pkg/upraises
import std/options
import ./udp/datagram
import ./errors

export chronos
export questionable
export options
export datagram
export errors
export upraises

template getOr*[T](o: Option[T], otherwise: untyped): T =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is valueOr in stew/results

if o.isSome():
o.unsafeGet()
else:
otherwise
6 changes: 3 additions & 3 deletions quic/connection.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type
udp: DatagramTransport
quic: QuicConnection
loop: Future[void]
onClose: ?proc() {.gcsafe, upraises: [].}
onClose: Option[proc() {.gcsafe, upraises: [].}]
closed: AsyncEvent
IncomingConnection = ref object of Connection
OutgoingConnection = ref object of Connection
Expand Down Expand Up @@ -59,8 +59,8 @@ method closeUdp(connection: OutgoingConnection) {.async.} =
proc disconnect(connection: Connection) {.async.} =
await connection.stopSending()
await connection.closeUdp()
if onClose =? connection.onClose:
onClose()
if connection.onClose.isSome():
(connection.onClose.unsafeGet())()
connection.closed.fire()

proc newIncomingConnection*(udp: DatagramTransport,
Expand Down
10 changes: 5 additions & 5 deletions quic/transport/ngtcp2/connection/closingstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ proc newClosingConnection*(finalDatagram: Datagram, ids: seq[ConnectionId],
state

proc sendFinalDatagram(state: ClosingConnection) =
if connection =? state.connection:
try:
connection.outgoing.putNoWait(state.finalDatagram)
except AsyncQueueFullError:
raise newException(QuicError, "Outgoing queue is full")
let connection = state.connection.getOr: return
try:
connection.outgoing.putNoWait(state.finalDatagram)
except AsyncQueueFullError:
raise newException(QuicError, "Outgoing queue is full")

{.push locks: "unknown".}

Expand Down
14 changes: 7 additions & 7 deletions quic/transport/ngtcp2/connection/disconnectingstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ./closedstate

type
DisconnectingConnection* = ref object of ConnectionState
connection: ?QuicConnection
connection: Option[QuicConnection]
disconnect: Future[void]
ids: seq[ConnectionId]

Expand All @@ -15,8 +15,8 @@ proc newDisconnectingConnection*(ids: seq[ConnectionId]):
DisconnectingConnection(ids: ids)

proc callDisconnect(connection: QuicConnection) {.async.} =
if disconnect =? connection.disconnect:
await disconnect()
let disconnect = connection.disconnect.getOr: return
await disconnect()

{.push locks: "unknown".}

Expand Down Expand Up @@ -44,12 +44,12 @@ method openStream(state: DisconnectingConnection,

method close(state: DisconnectingConnection) {.async.} =
await state.disconnect
if connection =? state.connection:
connection.switch(newClosedConnection())
let connection = state.connection.getOr: return
connection.switch(newClosedConnection())

method drop(state: DisconnectingConnection) {.async.} =
await state.disconnect
if connection =? state.connection:
connection.switch(newClosedConnection())
let connection = state.connection.getOr: return
connection.switch(newClosedConnection())

{.pop.}
18 changes: 9 additions & 9 deletions quic/transport/ngtcp2/connection/drainingstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ./closedstate

type
DrainingConnection* = ref object of ConnectionState
connection*: ?QuicConnection
connection*: Option[QuicConnection]
ids: seq[ConnectionId]
timeout: Timeout
duration: Duration
Expand Down Expand Up @@ -57,15 +57,15 @@ method openStream(state: DrainingConnection,

method close(state: DrainingConnection) {.async.} =
await state.done.wait()
if connection =? state.connection:
let disconnecting = newDisconnectingConnection(state.ids)
connection.switch(disconnecting)
await disconnecting.close()
let connection = state.connection.getOr: return
let disconnecting = newDisconnectingConnection(state.ids)
connection.switch(disconnecting)
await disconnecting.close()

method drop(state: DrainingConnection) {.async.} =
if connection =? state.connection:
let disconnecting = newDisconnectingConnection(state.ids)
connection.switch(disconnecting)
await disconnecting.drop()
let connection = state.connection.getOr: return
let disconnecting = newDisconnectingConnection(state.ids)
connection.switch(disconnecting)
await disconnecting.drop()

{.pop.}
38 changes: 19 additions & 19 deletions quic/transport/ngtcp2/connection/openstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ./openstreams

type
OpenConnection* = ref object of ConnectionState
quicConnection: ?QuicConnection
quicConnection: Option[QuicConnection]
ngtcp2Connection: Ngtcp2Connection
streams: OpenStreams

Expand All @@ -33,11 +33,11 @@ method enter(state: OpenConnection, connection: QuicConnection) =
procCall enter(ConnectionState(state), connection)
state.quicConnection = some connection
state.ngtcp2Connection.onNewId = some proc(id: ConnectionId) =
if onNewId =? connection.onNewId.option:
onNewId(id)
if isNil(connection.onNewId): return
connection.onNewId(id)
state.ngtcp2Connection.onRemoveId = some proc(id: ConnectionId) =
if onRemoveId =? connection.onRemoveId.option:
onRemoveId(id)
if isNil(connection.onRemoveId): return
connection.onRemoveId(id)
state.ngtcp2Connection.onSend = proc(datagram: Datagram) =
errorAsDefect:
connection.outgoing.putNoWait(datagram)
Expand All @@ -61,8 +61,8 @@ method send(state: OpenConnection) =

method receive(state: OpenConnection, datagram: Datagram) =
state.ngtcp2Connection.receive(datagram)
if state.ngtcp2Connection.isDraining and
quicConnection =? state.quicConnection:
let quicConnection = state.quicConnection.getOr: return
if state.ngtcp2Connection.isDraining:
let duration = state.ngtcp2Connection.closingDuration()
let ids = state.ids
let draining = newDrainingConnection(ids, duration)
Expand All @@ -71,25 +71,25 @@ method receive(state: OpenConnection, datagram: Datagram) =

method openStream(state: OpenConnection,
unidirectional: bool): Future[Stream] {.async.} =
without quicConnection =? state.quicConnection:
let quicConnection = state.quicConnection.getOr:
raise newException(QuicError, "connection is closed")
await quicConnection.handshake.wait()
result = state.ngtcp2Connection.openStream(unidirectional = unidirectional)
state.streams.add(result)

method close(state: OpenConnection) {.async.} =
if quicConnection =? state.quicConnection:
let finalDatagram = state.ngtcp2Connection.close()
let duration = state.ngtcp2Connection.closingDuration()
let ids = state.ids
let closing = newClosingConnection(finalDatagram, ids, duration)
quicConnection.switch(closing)
await closing.close()
let quicConnection = state.quicConnection.getOr: return
let finalDatagram = state.ngtcp2Connection.close()
let duration = state.ngtcp2Connection.closingDuration()
let ids = state.ids
let closing = newClosingConnection(finalDatagram, ids, duration)
quicConnection.switch(closing)
await closing.close()

method drop(state: OpenConnection) {.async.} =
if quicConnection =? state.quicConnection:
let disconnecting = newDisconnectingConnection(state.ids)
quicConnection.switch(disconnecting)
await disconnecting.drop()
let quicConnection = state.quicConnection.getOr: return
let disconnecting = newDisconnectingConnection(state.ids)
quicConnection.switch(disconnecting)
await disconnecting.drop()

{.pop.}
58 changes: 28 additions & 30 deletions quic/transport/ngtcp2/native/connection.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,28 @@ import ./pointers

type
Ngtcp2Connection* = ref object
conn*: ?ptr ngtcp2_conn
conn*: Option[ptr ngtcp2_conn]
path*: Path
buffer*: array[4096, byte]
flowing*: AsyncEvent
timeout*: Timeout
onSend*: proc(datagram: Datagram) {.gcsafe, upraises:[].}
onIncomingStream*: proc(stream: Stream)
onHandshakeDone*: proc()
onNewId*: ?proc(id: ConnectionId)
onRemoveId*: ?proc(id: ConnectionId)
onNewId*: Option[proc(id: ConnectionId)]
onRemoveId*: Option[proc(id: ConnectionId)]
Ngtcp2ConnectionClosed* = object of QuicError

proc destroy*(connection: Ngtcp2Connection) =
if conn =? connection.conn:
connection.timeout.stop()
ngtcp2_conn_del(conn)
connection.conn = none(ptr ngtcp2_conn)
connection.onSend = nil
connection.onIncomingStream = nil
connection.onHandshakeDone = nil
connection.onNewId = none proc(id: ConnectionId)
connection.onRemoveId = none proc(id: ConnectionId)
let conn = connection.conn.getOr: return
connection.timeout.stop()
ngtcp2_conn_del(conn)
connection.conn = none(ptr ngtcp2_conn)
connection.onSend = nil
connection.onIncomingStream = nil
connection.onHandshakeDone = nil
connection.onNewId = none proc(id: ConnectionId)
connection.onRemoveId = none proc(id: ConnectionId)

proc handleTimeout(connection: Ngtcp2Connection) {.gcsafe, upraises:[].}

Expand All @@ -47,16 +47,15 @@ proc newConnection*(path: Path): Ngtcp2Connection =
connection

proc ids*(connection: Ngtcp2Connection): seq[ConnectionId] =
without conn =? connection.conn:
return

let amount = ngtcp2_conn_get_num_scid(conn)
let
conn = connection.conn.getOr: return
amount = ngtcp2_conn_get_num_scid(conn)
var scids = newSeq[ngtcp2_cid](amount)
discard ngtcp2_conn_get_scid(conn, scids.toPtr)
scids.mapIt(ConnectionId(it.data[0..<it.datalen]))

proc updateTimeout*(connection: Ngtcp2Connection) =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

let expiry = ngtcp2_conn_get_expiry(conn)
Expand All @@ -70,7 +69,7 @@ proc trySend(connection: Ngtcp2Connection,
messagePtr: ptr byte = nil,
messageLen: uint = 0,
written: ptr int = nil): Datagram =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

var packetInfo: ngtcp2_pkt_info
Expand Down Expand Up @@ -128,7 +127,7 @@ proc send*(connection: Ngtcp2Connection,

proc tryReceive(connection: Ngtcp2Connection, datagram: openArray[byte],
ecn: ECN) =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

var packetInfo: ngtcp2_pkt_info
Expand All @@ -155,15 +154,14 @@ proc receive*(connection: Ngtcp2Connection, datagram: Datagram) =
connection.receive(datagram.data, datagram.ecn)

proc handleTimeout(connection: Ngtcp2Connection) =
without conn =? connection.conn:
return
let conn = connection.conn.getOr: return

errorAsDefect:
checkResult ngtcp2_conn_handle_expiry(conn, now())
connection.send()

proc close*(connection: Ngtcp2Connection): Datagram =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

var packetInfo: ngtcp2_pkt_info
Expand All @@ -182,54 +180,54 @@ proc close*(connection: Ngtcp2Connection): Datagram =
Datagram(data: data, ecn: ecn)

proc closingDuration*(connection: Ngtcp2Connection): Duration =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

3 * ngtcp2_conn_get_pto(conn).int64.nanoseconds

proc isDraining*(connection: Ngtcp2Connection): bool =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

ngtcp2_conn_is_in_draining_period(conn).bool

proc isHandshakeCompleted*(connection: Ngtcp2Connection): bool =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

ngtcp2_conn_get_handshake_completed(conn).bool

proc openUniStream*(connection: Ngtcp2Connection): int64 =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

checkResult ngtcp2_conn_open_uni_stream(conn, addr result, nil)

proc openBidiStream*(connection: Ngtcp2Connection): int64 =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

checkResult ngtcp2_conn_open_bidi_stream(conn, addr result, nil)

proc setStreamUserData*(connection: Ngtcp2Connection,
streamId: int64,
userdata: pointer) =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

checkResult ngtcp2_conn_set_stream_user_data(conn, streamId, userdata)

proc extendStreamOffset*(connection: Ngtcp2Connection,
streamId: int64,
amount: uint64) =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

checkResult conn.ngtcp2_conn_extend_max_stream_offset(streamId, amount)
conn.ngtcp2_conn_extend_max_offset(amount)

proc shutdownStream*(connection: Ngtcp2Connection, streamId: int64) =
without conn =? connection.conn:
let conn = connection.conn.getOr:
raise newException(Ngtcp2ConnectionClosed, "connection no longer exists")

checkResult ngtcp2_conn_shutdown_stream(conn, streamId, 0)
14 changes: 8 additions & 6 deletions quic/transport/ngtcp2/native/ids.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ proc getNewConnectionId(conn: ptr ngtcp2_conn,
id[] = newId.toCid
zeroMem(token, NGTCP2_STATELESS_RESET_TOKENLEN)

let connection = cast[Ngtcp2Connection](userData)
if onNewId =? connection.onNewId:
onNewId(newId)
let
connection = cast[Ngtcp2Connection](userData)
onNewId = connection.onNewId.getOr: return
onNewId(newId)

proc removeConnectionId(conn: ptr ngtcp2_conn,
id: ptr ngtcp2_cid,
userData: pointer): cint {.cdecl.} =
let connection = cast[Ngtcp2Connection](userData)
if onRemoveId =? connection.onRemoveId:
onRemoveId(id.toConnectionId)
let
connection = cast[Ngtcp2Connection](userData)
onRemoveId = connection.onRemoveId.getOr: return
onRemoveId(id.toConnectionId)

proc installConnectionIdCallback*(callbacks: var ngtcp2_conn_callbacks) =
callbacks.get_new_connection_id = getNewConnectionId
Expand Down
Loading