What is ShimmerCat QS?

ShimmerCat QS is a specially optimized HTTP/2 web-server. Its salient features are enabling website loading speed, web traffic analysis and modern telemetry. It takes the place of a conventional edge server and optimizes the website with strategic assets delivery and machine learning.

Embedded in the ShimmerCat Accelerator distribution, it connects to ShimmerCat's cloud analysis service to download site-specific optimization rules. The rules cover automatic HTTP/2 Push, bot protection, image prioritization and image optimization.

Server Architecture

ShimmerCat QS is a well-integrated, mostly monolitic program written in Haskell with two user-facing running modes: devlove and internet, with the first mode having some nice features and default for developers developing sites locally, and the second mode being better suited for Internet-facing workloads.

All instances of ShimmerCat need access to a Redis database, which is used to write compressed logs and manage instance-wide locks for the assets cache. Our distributions of ShimmerCat already come with Redis, and unless instructed otherwise, ShimmerCat can start and manage the Redis server on its own.

Runtime disposition

In devlove mode, ShimmerCat is just a single process that serves the requests. Internet mode is explained below and is slightly more complicated.

Worker lanes

In Internet mode, ShimmerCat uses a master process to help coordinate workers. Workers are the ones actually handling web traffic, and the amount of concurrent connections and streams that each worker can handle is essentially limited only by the amount of resources available to the process.

Workers are paired in so called worker lanes, which are a pair of passing + active worker. Whenever a worker is started, it tries to bind a Unix Domain socket which is pecific to its worker lane. If the process succeeds at binding the socket, it becomes passive, otherwise it becomes active. Only one process in the lane will ever be successfull at binding the socket so this mechanism allows the pair of processes in a lane to coordinate their role.

Whenever an active process terminates, it sends the main listening HTTPS socket to the passive member of the lane, which closes the Unix Domain socket and becomes active. As soon as the master process notices that a lane is incomplete, it spans a new worker on that lane.

The number of worker lanes can be adjusted using the --worker-count option.

Worker cycling

During normal operation, the active worker on each lane will live a random amount of time --bounded by the number of seconds in minAptoWait and maxAptoWait -- , after which it will send the listening HTTPS socket to the passive member of the pair and wait a bit to close active connections with minimal disruption. This is called worker cycling.

Normal worker cycling does not reload the configuration, but ShimmerCat has a special cycling operation that does reload the configuration, triggered by SIGHUP, see below.

Unix signals

ShimmerCat writes a file master.pid in the scratch folder with the PID of the master process. That PID can be used to send Unix signals to ShimmerCat, for example:

$ kill -SIGHUP `cat .shimmercat.loves.devs/master.pid`

The above command asks ShimmerCat to reload the workers with a fresh configuration from the configuration files.

ShimmerCat also reacts to the signals SIGTERM and SIGINT, which have the effect of quitting the server.

While running, the master process sends the signal SIGWINCH to the workers every 80 milliseconds. If a worker doesn't receive that signal in a set period of time, it exits. This mechanism is a safeguard for those occassions when the master is killed with SIGKILL, so that the workers also exit without being prompted by their contoller.

Filesystem access

In both modes, ShimmerCat QS uses a so-called "paths context", which is a small set of root paths referencing for example ShimmerCat's working directory and its scratch folder. Inside ShimmerCat, all path references are typed — Haskell, remember? — and made relative to a root in the paths context.

For the most part, ShimmerCat doesn't access any global files outside the roots in the paths context. The exception is the development CA repository, which is used to generate fake certificates for served websites if no certificate is configured in the scratch folder. In those cases, ShimmerCat uses a sub-component to manage the certificates called "mousebox", and said component stores a CA registry in $HOME/.config/mousebox.

Due to path isolation, it is very easy to run multiple instances of ShimmerCat side-by-side, each using a distinct configuration and a different set of files

Cache architecture and changelists

Internally, ShimmerCat classify resources to be served in three types. The first two are "static" (e.g. a Javascript file) and "dynamic" (e.g., dynamically generated HTML, or XHR requests). The third is a blend, so called generated assets. Both static and generated assets are acquired on the assumtion that doing so is expensive, so after they are acquired they are cached.

ShimmerCat's cache is very simple and stored in the scratch folder. For each resource cached, there is a folder <cache-ident>/<resource-ident>/<resource-representation>/ containing the cached files, most often in conjunction with alternative representations of the resource. Examples of representations are text compression formats or images re-encoded in alternative image formats.

When running in Internet mode, ShimmerCat runs a special process that we call the changelist daemon. This process reads changes on the original assets and uses them to invalidate their matching cache entries. In practice, those lists of changes must be created by a different program running where the files are.

How ShimmerCat QS is tested

Although there never is perfect testing, a good test suite is fundamental for a software enterprise. ShimmerCat QS uses three automated testing mechanisms:

We don't have a long release cycle, and instead rely in the following policies:

Logging and Telemetry

ShimmerCat emits logs in a binary format via Redis, and to stdout. At the moment, there is no way to handle the two outputs in different ways; both receive the same set of logs. When functioning in Internet mode, the logs are written to stdout by the master process, which reads them from the workers using Redis.

Besides logging, ShimmerCat includes built-in telemetry, which allows to query resource usage (TO-DO: add link) by the master+workers+changelists-daemon swarm.