Skip to content

Commit

Permalink
add startup callback to settings
Browse files Browse the repository at this point in the history
  • Loading branch information
bung87 committed Aug 3, 2023
1 parent 0f7b07f commit 7cb2acc
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
21 changes: 18 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/tests/*
!/tests/*.nim
!/tests/*.cfg
*
!**/
!*.*
*.out
.DS_Store
!.gitattributes
!.gitignore
!readme.md
!.gitkeep
!*.nim
!*.nims
!*.nimble
!*.h
!*.css
!*.html
*.exe
!*/
nimbledeps
14 changes: 14 additions & 0 deletions src/httpbeast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type

OnRequest* = proc (req: Request): Future[void] {.gcsafe.}

Startup = proc () {.closure, gcsafe.}

Settings* = object
port*: Port
bindAddr*: string
Expand All @@ -68,15 +70,23 @@ type
## 4096 for Linux/AMD64 and 128 for others.
## * listen(2) Linux manual page: https://www.man7.org/linux/man-pages/man2/listen.2.html
## * SYN packet handling int the wild: https://blog.cloudflare.com/syn-packet-handling-in-the-wild/
startup: Startup
## An optional callback can be provided to execute at the beginning of
## the `eventLoop` function for initializing thread variables or performing other related tasks.

HttpBeastDefect* = ref object of Defect

const
serverInfo = "HttpBeast"

proc doNothing(): Startup {.gcsafe.} =
result = proc () {.closure, gcsafe.} =
discard

proc initSettings*(port: Port = Port(8080),
bindAddr: string = "",
numThreads: int = 0,
startup: Startup = doNothing(),
domain = Domain.AF_INET,
reusePort = true,
listenBacklog = SOMAXCONN): Settings =
Expand All @@ -88,6 +98,7 @@ proc initSettings*(port: Port = Port(8080),
loggers: getHandlers(),
reusePort: reusePort,
listenBacklog: listenBacklog,
startup: startup
)

proc initData(fdKind: FdKind, ip = ""): Data =
Expand Down Expand Up @@ -333,6 +344,9 @@ proc eventLoop(
) =
let (onRequest, settings, isMainThread) = params

if settings.startup != nil:
settings.startup()

if not isMainThread:
# We are on a new thread. Re-add the loggers from the main thread.
for logger in settings.loggers:
Expand Down
7 changes: 7 additions & 0 deletions tests/startup.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
charset = "utf-8"
[Package]
name = "hello"
--threads:on
[Author]
name = "nim-lang"
website = "nim-lang.org"
41 changes: 41 additions & 0 deletions tests/startup.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os, options, asyncdispatch, parsecfg, strutils, streams
import httpbeast

const CurDir = currentSourcePath.parentDir

var threadsOn {.threadvar.}: bool
var name {.threadvar.}: string

proc onRequest(req: Request): Future[void] =
if req.httpMethod == some(HttpGet):
case req.path.get()
of "/":
req.send("name:$#,threads:$#." % [name, $threadsOn])
else:
req.send(Http404)

var startup = proc () =
let configFile = CurDir / "startup.ini"
var f = newFileStream(configFile, fmRead)
assert f != nil, "cannot open " & configFile
var p: CfgParser
var section: string
open(p, f, configFile)
while true:
var e = next(p)
case e.kind
of cfgEof: break
of cfgSectionStart: ## a `[section]` has been parsed
section = e.section
of cfgKeyValuePair:
if section == "Package" and e.key == "name":
name = e.value
of cfgOption:
if e.key == "threads":
if e.value == "on":
threadsOn = true
of cfgError:
echo e.msg
close(p)

run(onRequest, initSettings(startup = startup))

0 comments on commit 7cb2acc

Please sign in to comment.