fix v3 backwards compatibility for callbacks (#481)
Because the callback types were used explicitly in some consumers of chronos, the change of type introduces a backwards incompatibility preventing a smooth transition to v4 for code that doesn't uses `raises`. This PR restores backwards compatibility at the expense of introducing a new type with a potentially ugly name - that said, there is already precedence for using numbered names to provide new error handling strategy in chronos.
This commit is contained in:
parent
48b2b08cfb
commit
e38ceb5378
|
@ -63,18 +63,22 @@ type
|
||||||
HttpResponseState* {.pure.} = enum
|
HttpResponseState* {.pure.} = enum
|
||||||
Empty, Prepared, Sending, Finished, Failed, Cancelled, Default
|
Empty, Prepared, Sending, Finished, Failed, Cancelled, Default
|
||||||
|
|
||||||
HttpProcessCallback* =
|
# TODO Evaluate naming of raises-annotated callbacks
|
||||||
|
HttpProcessCallback2* =
|
||||||
proc(req: RequestFence): Future[HttpResponseRef] {.
|
proc(req: RequestFence): Future[HttpResponseRef] {.
|
||||||
async: (raises: [CancelledError, HttpResponseError]), gcsafe.}
|
async: (raises: [CancelledError, HttpResponseError]).}
|
||||||
|
|
||||||
|
HttpProcessCallback* {.deprecated.} =
|
||||||
|
proc(req: RequestFence): Future[HttpResponseRef] {.async.}
|
||||||
|
|
||||||
HttpConnectionCallback* =
|
HttpConnectionCallback* =
|
||||||
proc(server: HttpServerRef,
|
proc(server: HttpServerRef,
|
||||||
transp: StreamTransport): Future[HttpConnectionRef] {.
|
transp: StreamTransport): Future[HttpConnectionRef] {.
|
||||||
async: (raises: [CancelledError, HttpConnectionError]), gcsafe.}
|
async: (raises: [CancelledError, HttpConnectionError]).}
|
||||||
|
|
||||||
HttpCloseConnectionCallback* =
|
HttpCloseConnectionCallback* =
|
||||||
proc(connection: HttpConnectionRef): Future[void] {.
|
proc(connection: HttpConnectionRef): Future[void] {.
|
||||||
async: (raises: []), gcsafe.}
|
async: (raises: []).}
|
||||||
|
|
||||||
HttpConnectionHolder* = object of RootObj
|
HttpConnectionHolder* = object of RootObj
|
||||||
connection*: HttpConnectionRef
|
connection*: HttpConnectionRef
|
||||||
|
@ -103,7 +107,7 @@ type
|
||||||
bufferSize*: int
|
bufferSize*: int
|
||||||
maxHeadersSize*: int
|
maxHeadersSize*: int
|
||||||
maxRequestBodySize*: int
|
maxRequestBodySize*: int
|
||||||
processCallback*: HttpProcessCallback
|
processCallback*: HttpProcessCallback2
|
||||||
createConnCallback*: HttpConnectionCallback
|
createConnCallback*: HttpConnectionCallback
|
||||||
|
|
||||||
HttpServerRef* = ref HttpServer
|
HttpServerRef* = ref HttpServer
|
||||||
|
@ -182,7 +186,7 @@ proc createConnection(server: HttpServerRef,
|
||||||
|
|
||||||
proc new*(htype: typedesc[HttpServerRef],
|
proc new*(htype: typedesc[HttpServerRef],
|
||||||
address: TransportAddress,
|
address: TransportAddress,
|
||||||
processCallback: HttpProcessCallback,
|
processCallback: HttpProcessCallback2,
|
||||||
serverFlags: set[HttpServerFlags] = {},
|
serverFlags: set[HttpServerFlags] = {},
|
||||||
socketFlags: set[ServerFlags] = {ReuseAddr},
|
socketFlags: set[ServerFlags] = {ReuseAddr},
|
||||||
serverUri = Uri(),
|
serverUri = Uri(),
|
||||||
|
@ -236,6 +240,49 @@ proc new*(htype: typedesc[HttpServerRef],
|
||||||
)
|
)
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
||||||
|
proc new*(htype: typedesc[HttpServerRef],
|
||||||
|
address: TransportAddress,
|
||||||
|
processCallback: HttpProcessCallback,
|
||||||
|
serverFlags: set[HttpServerFlags] = {},
|
||||||
|
socketFlags: set[ServerFlags] = {ReuseAddr},
|
||||||
|
serverUri = Uri(),
|
||||||
|
serverIdent = "",
|
||||||
|
maxConnections: int = -1,
|
||||||
|
bufferSize: int = 4096,
|
||||||
|
backlogSize: int = DefaultBacklogSize,
|
||||||
|
httpHeadersTimeout = 10.seconds,
|
||||||
|
maxHeadersSize: int = 8192,
|
||||||
|
maxRequestBodySize: int = 1_048_576,
|
||||||
|
dualstack = DualStackType.Auto): HttpResult[HttpServerRef] {.
|
||||||
|
deprecated: "raises missing from process callback".} =
|
||||||
|
|
||||||
|
proc processCallback2(req: RequestFence): Future[HttpResponseRef] {.
|
||||||
|
async: (raises: [CancelledError, HttpResponseError]).} =
|
||||||
|
try:
|
||||||
|
await processCallback(req)
|
||||||
|
except CancelledError as exc:
|
||||||
|
raise exc
|
||||||
|
except HttpResponseError as exc:
|
||||||
|
raise exc
|
||||||
|
except CatchableError as exc:
|
||||||
|
# Emulate 3.x behavior
|
||||||
|
raise (ref HttpCriticalError)(msg: exc.msg, code: Http503)
|
||||||
|
|
||||||
|
HttpServerRef.new(
|
||||||
|
address = address,
|
||||||
|
processCallback = processCallback2,
|
||||||
|
serverFlags = serverFlags,
|
||||||
|
socketFlags = socketFlags,
|
||||||
|
serverUri = serverUri,
|
||||||
|
serverIdent = serverIdent,
|
||||||
|
maxConnections = maxConnections,
|
||||||
|
bufferSize = bufferSize,
|
||||||
|
backlogSize = backlogSize,
|
||||||
|
httpHeadersTimeout = httpHeadersTimeout,
|
||||||
|
maxHeadersSize = maxHeadersSize,
|
||||||
|
maxRequestBodySize = maxRequestBodySize,
|
||||||
|
dualstack = dualstack)
|
||||||
|
|
||||||
proc getServerFlags(req: HttpRequestRef): set[HttpServerFlags] =
|
proc getServerFlags(req: HttpRequestRef): set[HttpServerFlags] =
|
||||||
var defaultFlags: set[HttpServerFlags] = {}
|
var defaultFlags: set[HttpServerFlags] = {}
|
||||||
if isNil(req): return defaultFlags
|
if isNil(req): return defaultFlags
|
||||||
|
|
|
@ -82,7 +82,7 @@ proc createSecConnection(server: HttpServerRef,
|
||||||
|
|
||||||
proc new*(htype: typedesc[SecureHttpServerRef],
|
proc new*(htype: typedesc[SecureHttpServerRef],
|
||||||
address: TransportAddress,
|
address: TransportAddress,
|
||||||
processCallback: HttpProcessCallback,
|
processCallback: HttpProcessCallback2,
|
||||||
tlsPrivateKey: TLSPrivateKey,
|
tlsPrivateKey: TLSPrivateKey,
|
||||||
tlsCertificate: TLSCertificate,
|
tlsCertificate: TLSCertificate,
|
||||||
serverFlags: set[HttpServerFlags] = {},
|
serverFlags: set[HttpServerFlags] = {},
|
||||||
|
@ -145,3 +145,53 @@ proc new*(htype: typedesc[SecureHttpServerRef],
|
||||||
secureFlags: secureFlags
|
secureFlags: secureFlags
|
||||||
)
|
)
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
||||||
|
proc new*(htype: typedesc[SecureHttpServerRef],
|
||||||
|
address: TransportAddress,
|
||||||
|
processCallback: HttpProcessCallback,
|
||||||
|
tlsPrivateKey: TLSPrivateKey,
|
||||||
|
tlsCertificate: TLSCertificate,
|
||||||
|
serverFlags: set[HttpServerFlags] = {},
|
||||||
|
socketFlags: set[ServerFlags] = {ReuseAddr},
|
||||||
|
serverUri = Uri(),
|
||||||
|
serverIdent = "",
|
||||||
|
secureFlags: set[TLSFlags] = {},
|
||||||
|
maxConnections: int = -1,
|
||||||
|
bufferSize: int = 4096,
|
||||||
|
backlogSize: int = DefaultBacklogSize,
|
||||||
|
httpHeadersTimeout = 10.seconds,
|
||||||
|
maxHeadersSize: int = 8192,
|
||||||
|
maxRequestBodySize: int = 1_048_576,
|
||||||
|
dualstack = DualStackType.Auto
|
||||||
|
): HttpResult[SecureHttpServerRef] {.
|
||||||
|
deprecated: "raises missing from process callback".} =
|
||||||
|
proc processCallback2(req: RequestFence): Future[HttpResponseRef] {.
|
||||||
|
async: (raises: [CancelledError, HttpResponseError]).} =
|
||||||
|
try:
|
||||||
|
await processCallback(req)
|
||||||
|
except CancelledError as exc:
|
||||||
|
raise exc
|
||||||
|
except HttpResponseError as exc:
|
||||||
|
raise exc
|
||||||
|
except CatchableError as exc:
|
||||||
|
# Emulate 3.x behavior
|
||||||
|
raise (ref HttpCriticalError)(msg: exc.msg, code: Http503)
|
||||||
|
|
||||||
|
SecureHttpServerRef.new(
|
||||||
|
address = address,
|
||||||
|
processCallback = processCallback2,
|
||||||
|
tlsPrivateKey = tlsPrivateKey,
|
||||||
|
tlsCertificate = tlsCertificate,
|
||||||
|
serverFlags = serverFlags,
|
||||||
|
socketFlags = socketFlags,
|
||||||
|
serverUri = serverUri,
|
||||||
|
serverIdent = serverIdent,
|
||||||
|
secureFlags = secureFlags,
|
||||||
|
maxConnections = maxConnections,
|
||||||
|
bufferSize = bufferSize,
|
||||||
|
backlogSize = backlogSize,
|
||||||
|
httpHeadersTimeout = httpHeadersTimeout,
|
||||||
|
maxHeadersSize = maxHeadersSize,
|
||||||
|
maxRequestBodySize = maxRequestBodySize,
|
||||||
|
dualstack = dualstack
|
||||||
|
)
|
|
@ -115,14 +115,15 @@ else:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
type
|
type
|
||||||
StreamCallback* = proc(server: StreamServer,
|
# TODO evaluate naming of raises-annotated callbacks
|
||||||
client: StreamTransport) {.async: (raises: []).}
|
StreamCallback2* = proc(server: StreamServer,
|
||||||
|
client: StreamTransport) {.async: (raises: []).}
|
||||||
## New remote client connection callback
|
## New remote client connection callback
|
||||||
## ``server`` - StreamServer object.
|
## ``server`` - StreamServer object.
|
||||||
## ``client`` - accepted client transport.
|
## ``client`` - accepted client transport.
|
||||||
|
|
||||||
UnsafeStreamCallback* = proc(server: StreamServer,
|
StreamCallback* = proc(server: StreamServer,
|
||||||
client: StreamTransport) {.async.}
|
client: StreamTransport) {.async.}
|
||||||
## Connection callback that doesn't check for exceptions at compile time
|
## Connection callback that doesn't check for exceptions at compile time
|
||||||
## ``server`` - StreamServer object.
|
## ``server`` - StreamServer object.
|
||||||
## ``client`` - accepted client transport.
|
## ``client`` - accepted client transport.
|
||||||
|
@ -135,7 +136,7 @@ type
|
||||||
|
|
||||||
StreamServer* = ref object of SocketServer
|
StreamServer* = ref object of SocketServer
|
||||||
## StreamServer object
|
## StreamServer object
|
||||||
function*: StreamCallback # callback which will be called after new
|
function*: StreamCallback2 # callback which will be called after new
|
||||||
# client accepted
|
# client accepted
|
||||||
init*: TransportInitCallback # callback which will be called before
|
init*: TransportInitCallback # callback which will be called before
|
||||||
# transport for new client
|
# transport for new client
|
||||||
|
@ -1870,7 +1871,7 @@ proc getBacklogSize(backlog: int): cint =
|
||||||
cint(backlog)
|
cint(backlog)
|
||||||
|
|
||||||
proc createStreamServer*(host: TransportAddress,
|
proc createStreamServer*(host: TransportAddress,
|
||||||
cbproc: StreamCallback,
|
cbproc: StreamCallback2,
|
||||||
flags: set[ServerFlags] = {},
|
flags: set[ServerFlags] = {},
|
||||||
sock: AsyncFD = asyncInvalidSocket,
|
sock: AsyncFD = asyncInvalidSocket,
|
||||||
backlog: int = DefaultBacklogSize,
|
backlog: int = DefaultBacklogSize,
|
||||||
|
@ -2092,7 +2093,7 @@ proc createStreamServer*(host: TransportAddress,
|
||||||
sres
|
sres
|
||||||
|
|
||||||
proc createStreamServer*(host: TransportAddress,
|
proc createStreamServer*(host: TransportAddress,
|
||||||
cbproc: UnsafeStreamCallback,
|
cbproc: StreamCallback,
|
||||||
flags: set[ServerFlags] = {},
|
flags: set[ServerFlags] = {},
|
||||||
sock: AsyncFD = asyncInvalidSocket,
|
sock: AsyncFD = asyncInvalidSocket,
|
||||||
backlog: int = DefaultBacklogSize,
|
backlog: int = DefaultBacklogSize,
|
||||||
|
@ -2124,11 +2125,11 @@ proc createStreamServer*(host: TransportAddress,
|
||||||
udata: pointer = nil,
|
udata: pointer = nil,
|
||||||
dualstack = DualStackType.Auto): StreamServer {.
|
dualstack = DualStackType.Auto): StreamServer {.
|
||||||
raises: [TransportOsError].} =
|
raises: [TransportOsError].} =
|
||||||
createStreamServer(host, StreamCallback(nil), flags, sock, backlog, bufferSize,
|
createStreamServer(host, StreamCallback2(nil), flags, sock, backlog, bufferSize,
|
||||||
child, init, cast[pointer](udata), dualstack)
|
child, init, cast[pointer](udata), dualstack)
|
||||||
|
|
||||||
proc createStreamServer*[T](host: TransportAddress,
|
proc createStreamServer*[T](host: TransportAddress,
|
||||||
cbproc: StreamCallback,
|
cbproc: StreamCallback2,
|
||||||
flags: set[ServerFlags] = {},
|
flags: set[ServerFlags] = {},
|
||||||
udata: ref T,
|
udata: ref T,
|
||||||
sock: AsyncFD = asyncInvalidSocket,
|
sock: AsyncFD = asyncInvalidSocket,
|
||||||
|
@ -2144,7 +2145,7 @@ proc createStreamServer*[T](host: TransportAddress,
|
||||||
child, init, cast[pointer](udata), dualstack)
|
child, init, cast[pointer](udata), dualstack)
|
||||||
|
|
||||||
proc createStreamServer*[T](host: TransportAddress,
|
proc createStreamServer*[T](host: TransportAddress,
|
||||||
cbproc: UnsafeStreamCallback,
|
cbproc: StreamCallback,
|
||||||
flags: set[ServerFlags] = {},
|
flags: set[ServerFlags] = {},
|
||||||
udata: ref T,
|
udata: ref T,
|
||||||
sock: AsyncFD = asyncInvalidSocket,
|
sock: AsyncFD = asyncInvalidSocket,
|
||||||
|
@ -2172,7 +2173,7 @@ proc createStreamServer*[T](host: TransportAddress,
|
||||||
raises: [TransportOsError].} =
|
raises: [TransportOsError].} =
|
||||||
var fflags = flags + {GCUserData}
|
var fflags = flags + {GCUserData}
|
||||||
GC_ref(udata)
|
GC_ref(udata)
|
||||||
createStreamServer(host, StreamCallback(nil), fflags, sock, backlog, bufferSize,
|
createStreamServer(host, StreamCallback2(nil), fflags, sock, backlog, bufferSize,
|
||||||
child, init, cast[pointer](udata), dualstack)
|
child, init, cast[pointer](udata), dualstack)
|
||||||
|
|
||||||
proc getUserData*[T](server: StreamServer): T {.inline.} =
|
proc getUserData*[T](server: StreamServer): T {.inline.} =
|
||||||
|
|
|
@ -85,7 +85,7 @@ suite "HTTP client testing suite":
|
||||||
res
|
res
|
||||||
|
|
||||||
proc createServer(address: TransportAddress,
|
proc createServer(address: TransportAddress,
|
||||||
process: HttpProcessCallback, secure: bool): HttpServerRef =
|
process: HttpProcessCallback2, secure: bool): HttpServerRef =
|
||||||
let
|
let
|
||||||
socketFlags = {ServerFlags.TcpNoDelay, ServerFlags.ReuseAddr}
|
socketFlags = {ServerFlags.TcpNoDelay, ServerFlags.ReuseAddr}
|
||||||
serverFlags = {HttpServerFlags.Http11Pipeline}
|
serverFlags = {HttpServerFlags.Http11Pipeline}
|
||||||
|
|
Loading…
Reference in New Issue