CS2D: Funnel

For a while now it's been possible to make requests from CS2D to external resources, and receive data in response. However, the game's built-in HTTP communication channel is slow and fairly primitive, and using LuaSocket requires JIT. This also means that receiving data from external resources requires polling them, and because reqhttp is slow, the polling takes a while.

My previous post discussed an approach to parallelism using JIT and forking to simulate "threads", which makes it possible to run a blocking I/O process in parallel to the main game loop. However, this approach is fairly resource intensive, since each child process needs about the same amount of resources as the parent CS2D server. The simplest solution then becomes using "companion" programs side-by-side, as that blog post mentioned.

Enter Funnel. Funnel is a simple solution for external communication in two parts: a Go HTTP server and FIFO queue (Funnel itself), and a Lua module for CS2D (XCH). The principle is simple: both parts use a common file to exchange one message at a time. Each message has a channel (for filtering) and a body. HTTP requests to Funnel add messages to the queue, and Funnel outputs a single message from the queue into a shared file if that file is empty and not locked. The Lua module checks the file for data every 100 ms, and if there is a message, it consumes it and calls any listeners listening to data on a given channel, clearing the file in the process. This means that messages are passed from the Go dispatcher to the game server only as quickly as the Lua module can consume them, which sacrifices speed for guaranteed message arrival.

The Funnel companion app is available on Docker as cs2d-funnel; the source code is available on GitHub. It is designed to easily integrate with a Docker setup for server hosting. To illustrate Funnel's usage for communication with external services, I've built a simple message broker that sends messages consumed from an AMQP queue to Funnel, also available on GitHub and Docker as engin33r/cs2d-funnel-amqp. The GitHub repository includes an example Lua script that implements cross-server chat (CS2D JIT required for the script), and a comprehensive Docker compose example for hosting a server with CS2D JIT support and AMQP connectivity.

While the included example is trivial, even that could be built upon to easily implement remote server control and status checks for web panels and other external tools. Hope you have fun with this; suggestions and PRs always welcome!

Show Comments