A threaded http server for future projects
src | ||
tests | ||
albaHttpServer.nimble | ||
README.md |
What is this?
This is alba Http Server. It is like the threaded dispatchers of old, written in Nim. This includes the following:
- A simplified HTTP Server which does NOT use any ASYNC due to memory issues in Nim at the current moment. It also creates its own "Request" object compared to the one seen in the stdlib.
Request* = object
path* : Uri
verb* : HttpMethod
headers* : Table[string, string]
socket* : Socket
address* : string
- A threaded dispatcher which allocates requests to the thread with the least amount of requests currently pending. This is ideal for high-cpu using APIs.
It works using the following objects:
type
ThreadScheduler*[T] = object
initFunction : proc(): T{.gcsafe.}
paths : Table[string, proc(a : Request, b : T){.gcsafe.}]
ThreadHandler*[T] = object
Scheduler : ThreadScheduler[T]
communications: seq[ptr Channel[ptr Request]]
cpuCount : int
Where, T is the thread-local storage. For example
type ControllerData* = object
# Database connection for db operations
db : DbConn
# Standard response header, for all responses
headers : TableRef[string, string]
# Pre-generated response
dbInfo : string
# Pre-generated data
allUsers : seq[string]
All endpoints registered in paths must take the type [T] in.
Usage
import albaHttpServer
import httpclient
import tables
import net
type MyObject = object
foo : string
bar : string
proc doThing(a : Request, b : MyObject) =
if a.verb != HttpGet:
a.respond(405, "")
a.respond(200, b.foo)
proc init() : MyObject =
result.foo = "hello"
result.bar = "world"
var paths : Table[string, proc(a: Request, b: MyObject){.gcsafe.}]
paths["/"] = doThing
let handler = initHandler[MyObject](init, paths)
let socket = newSocket()
socket.setSockOpt(OptReusePort, true)
socket.bindAddr(Port(5000))
socket.listen()
while true:
var request = getRequest(socket)
#Checks for invalid requests.
if request.isNone():
continue
else:
let req = request.get()
dispatch(req, handler)