Foxhole is a neko based standalone webserver, that closely imitates the neko.Web
API. At its current stage it is primarily intended as a replacement for nekotools server
, but it may become a viable option for production use.
It has support for parsing multipart request bodies and removes post body size limitations.
You can write Foxhole based web applications almost exactly the same way you would write neko.Web
based applications, except for the entry point. With the latter, you compile a neko module and use mod_neko
or mod_tora
or nekotools server
as a container. The main entry point acts as the request handler, unless use use neko.Web.cacheModule
to change it. Foxhole is different in that by using -lib foxhole
the server is compiled into the module and you will have to launch it using foxhole.Web.run
.
Here's what it comes down to:
class Main {
static function respond() {
//do something here
}
static function main() {
//initialize database, load config etc.
#if foxhole
foxhole.Web.run({
handler: respond,
});
#else
neko.Web.cacheModule(respond);
respond();
#end
}
}
Should you not call foxhole.Web.run
, the application will just quit. Should you call it multiple times, you will bind multiple servers. Whether or not that is actually useful remains to be seen. Doing so is advised against.
If you launch Foxhole with { watch: true }
it will watch its own file and exit as soon as it changes. If your IDE starts your neko module as soon as it is compiled, then this will do the trick. Otherwise using this tiny helper you can make it run forever like so
haxe --run Forever neko <yourModule>.n
Foxhole uses multiple worker threads to execute requests. By default, progress in these threads is mutually exclusive. However with Foxhole.Web.inParallel(task)
you can execute a task
while giving other worker threads the opportunity to progress. Good use cases would be:
The underlying implementation is really quite simple. There is one common lock, that each worker acquires before processing the request, and then releases when done. If you call inParallel
the current worker releases that lock and starts executing the supplied task. Once done, it reacquires the lock. When in doubt, don't use inParallel
and you will be fine.
Foxhole is based on tink_http
, which provides an asynchronous cross platform API for handling HTTP. The server runs in an event loop on the main thread. Requests are then handed off to worker threads that handle them synchronously, as explained in the section above. The output is buffered and once the handler has completed, the buffer is streamed onto the outgoing connection. Streaming output will be supported in the future.
Foxhole is not field tested (nor properly unit tested). There are no known bugs. Instead, there are - in all likelihood - unknown bugs. You have been warned.
However, presuming that those bugs can be identified and resolved in the foreseeable future, Foxhole presents an interesting alternative for deploying neko based web applications. It is mostly likely not a very good idea to directly expose it to the outside world, but instead it should be proxied behind a reliable HTTP server as nginx and adequately supervised - a relatively common setup for nodejs. The proxy can take care of HTTPS offloading, static file serving, DoS protection and so forth.
Preliminary benchmarking seem to indicate that Foxhole introduces reasonable overhead (less than 1ms per request in apache benchmarks) and shows grace under pressure (stays under said 1ms even with 10000 concurrent requests). Since it interfaces with the outside world through HTTP rather than CGI, FastCGI, Tora or whatnot, it is easy to integrate with every webserver that is able to act as an HTTP proxy, which certainly covers all the established ones.
Given there is quite some room for optimization and its support to parallelize certain task, it may become a good choice for certain classes of performance critical applications.
In general, Foxhole is not neko-specific. Both java and cpp support are within reach. This depends largely on tink_http being properly implemented on those platforms.