From 3902a5f484d0cc9ab597e3208b42a1d9abde1983 Mon Sep 17 00:00:00 2001 From: nitely Date: Sun, 26 Jan 2025 11:31:49 -0300 Subject: [PATCH 1/3] server run with threads --- src/hyperx/server.nim | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/hyperx/server.nim b/src/hyperx/server.nim index 9914b27..b1e3ba1 100644 --- a/src/hyperx/server.nim +++ b/src/hyperx/server.nim @@ -208,3 +208,52 @@ proc serve*( await lt.spawn processClientHandler(client, callback) finally: await lt.join() + +type WorkerContext = object + hostname: cstring + port: Port + callback: StreamCallback + sslCertFile, sslKeyFile: cstring + maxConnections: int + +proc workerImpl(ctx: WorkerContext, ssl: static[bool] = true) = + var server = newServer( + ctx.localHost, ctx.localPort, ctx.certFile, ctx.keyFile, ssl = ssl + ) + waitFor server.serve(ctx.callback, ctx.maxConnections) + +proc workerSsl(ctx: ptr WorkerContext) {.thread.} = + workerImpl(ctx[], ssl = true) + +proc worker(ctx: ptr WorkerContext) {.thread.} = + workerImpl(ctx[], ssl = false) + +proc run*( + hostname: string, + port: Port, + callback: StreamCallback, + sslCertFile = "", + sslKeyFile = "", + maxConnections = defaultMaxConns, + threads = 1, + ssl: static[bool] = true +) = + let ctx = WorkerContext( + hostname: hostname, + port: port, + callback: callback, + sslCertFile: sslCertFile, + sslKeyFile: sslKeyFile, + maxConnections: maxConnections + ) + if threads == 1: + workerImpl(ctx, ssl = ssl) + else: + var threads = newSeq[Thread[ptr WorkerContext]](threads) + for i in 0 .. threads.len-1: + when ssl: + createThread(threads[i], workerSsl, addr ctx) + else: + createThread(threads[i], worker, addr ctx) + for i in 0 .. threads.len-1: + joinThread(threads[i]) From fe238eb5241c4e968f2e98fb1950ce6eb1dcea25 Mon Sep 17 00:00:00 2001 From: nitely Date: Mon, 27 Jan 2025 19:42:06 -0300 Subject: [PATCH 2/3] wip --- src/hyperx/server.nim | 21 +++++++++++++-------- tests/functional/tserver.nim | 2 +- tests/functional/tservermultithread.nim | 23 ++++++++--------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/hyperx/server.nim b/src/hyperx/server.nim index b1e3ba1..fd62446 100644 --- a/src/hyperx/server.nim +++ b/src/hyperx/server.nim @@ -209,18 +209,22 @@ proc serve*( finally: await lt.join() -type WorkerContext = object - hostname: cstring - port: Port - callback: StreamCallback - sslCertFile, sslKeyFile: cstring - maxConnections: int +type + WorkerContext = object + hostname: cstring + port: Port + callback: StreamCallback + sslCertFile, sslKeyFile: cstring + maxConnections: int proc workerImpl(ctx: WorkerContext, ssl: static[bool] = true) = var server = newServer( - ctx.localHost, ctx.localPort, ctx.certFile, ctx.keyFile, ssl = ssl + $ctx.hostname, ctx.port, $ctx.sslCertFile, $ctx.sslKeyFile, ssl = ssl ) - waitFor server.serve(ctx.callback, ctx.maxConnections) + try: + waitFor server.serve(ctx.callback, ctx.maxConnections) + finally: + destroyServerSslContext() proc workerSsl(ctx: ptr WorkerContext) {.thread.} = workerImpl(ctx[], ssl = true) @@ -228,6 +232,7 @@ proc workerSsl(ctx: ptr WorkerContext) {.thread.} = proc worker(ctx: ptr WorkerContext) {.thread.} = workerImpl(ctx[], ssl = false) +# XXX graceful shutdown proc run*( hostname: string, port: Port, diff --git a/tests/functional/tserver.nim b/tests/functional/tserver.nim index dd1c300..220162d 100644 --- a/tests/functional/tserver.nim +++ b/tests/functional/tserver.nim @@ -11,7 +11,7 @@ from ../../src/hyperx/errors import hyxCancel const certFile = getEnv "HYPERX_TEST_CERTFILE" const keyFile = getEnv "HYPERX_TEST_KEYFILE" -proc processStream(strm: ClientStream) {.async.} = +proc processStream*(strm: ClientStream) {.async.} = let data = new string await strm.recvHeaders(data) if "x-flow-control-check" in data[]: diff --git a/tests/functional/tservermultithread.nim b/tests/functional/tservermultithread.nim index d2c50f5..6102c3f 100644 --- a/tests/functional/tservermultithread.nim +++ b/tests/functional/tservermultithread.nim @@ -10,24 +10,17 @@ import ./tutils const certFile = getEnv "HYPERX_TEST_CERTFILE" const keyFile = getEnv "HYPERX_TEST_KEYFILE" -proc main() {.async.} = - echo "Serving forever" - var server = newServer( - localHost, localMultiThreadPort, certFile, keyFile - ) - await server.serve() - # XXX graceful shutdown -proc worker {.thread.} = - waitFor main() - proc run = - var threads = newSeq[Thread[void]](4) - for i in 0 .. threads.len-1: - createThread(threads[i], worker) - for i in 0 .. threads.len-1: - joinThread(threads[i]) + run( + localHost, + localMultiThreadPort, + processStream, + certFile, + keyFile, + threads = 4 + ) when isMainModule: run() From 108573f59a3c972469f351e4ade788cc54e877dc Mon Sep 17 00:00:00 2001 From: nitely Date: Mon, 27 Jan 2025 19:49:07 -0300 Subject: [PATCH 3/3] wip --- src/hyperx/server.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hyperx/server.nim b/src/hyperx/server.nim index fd62446..2a3f104 100644 --- a/src/hyperx/server.nim +++ b/src/hyperx/server.nim @@ -226,7 +226,7 @@ proc workerImpl(ctx: WorkerContext, ssl: static[bool] = true) = finally: destroyServerSslContext() -proc workerSsl(ctx: ptr WorkerContext) {.thread.} = +proc workerSsl(ctx: ptr WorkerContext) {.thread, definedSsl.} = workerImpl(ctx[], ssl = true) proc worker(ctx: ptr WorkerContext) {.thread.} = @@ -243,6 +243,8 @@ proc run*( threads = 1, ssl: static[bool] = true ) = + when ssl and not isSslDefined: + {.error: "this lib needs -d:ssl".} let ctx = WorkerContext( hostname: hostname, port: port,