Skip to content

Commit

Permalink
Server run with threads (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
nitely authored Jan 27, 2025
1 parent 1aeddd8 commit 93a6cee
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 16 deletions.
56 changes: 56 additions & 0 deletions src/hyperx/server.nim
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,59 @@ 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.hostname, ctx.port, $ctx.sslCertFile, $ctx.sslKeyFile, ssl = ssl
)
try:
waitFor server.serve(ctx.callback, ctx.maxConnections)
finally:
destroyServerSslContext()

proc workerSsl(ctx: ptr WorkerContext) {.thread, definedSsl.} =
workerImpl(ctx[], ssl = true)

proc worker(ctx: ptr WorkerContext) {.thread.} =
workerImpl(ctx[], ssl = false)

# XXX graceful shutdown
proc run*(
hostname: string,
port: Port,
callback: StreamCallback,
sslCertFile = "",
sslKeyFile = "",
maxConnections = defaultMaxConns,
threads = 1,
ssl: static[bool] = true
) =
when ssl and not isSslDefined:
{.error: "this lib needs -d:ssl".}
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])
2 changes: 1 addition & 1 deletion tests/functional/tserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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[]:
Expand Down
23 changes: 8 additions & 15 deletions tests/functional/tservermultithread.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 93a6cee

Please sign in to comment.