Skip to content

What is ShimmerCat QS?

ShimmerCat QS is a specially optimized HTTP/2 web-server. We use the QS suffix to talk specifically of the web server software and differentiate it from the company ("ShimmerCat AB") and our SaaS service (which our techies don't call "ShimmerCat", but that somebody else might).

Our goal with ShimmerCat QS is to enhance website loading speed, both via built-in technologies and – specially– in cooperation with our data-analysis and rule creation SaaS service. We call the combination of the two things the "ShimmerCat Accelerator".

As a side effect, ShimmerCat QS supports web traffic analysis and modern telemetry.

When embedded in the ShimmerCat Accelerator distribution (we just call it "sc_pack"), it connects to our SaaS service to download site-specific optimization rules covering automatic HTTP/2 Push, bot protection, image prioritization and image optimization.

ShimmerCat QS can be used as a standalone (as in "disconnected from our SaaS service and not embedded in our ShimmerCat Accelerator distribution") web server and as a development tool. The standalone version of ShimmerCat can be downloaded from here.

Server Architecture

ShimmerCat QS is a well-integrated, mostly monolithic program written in Haskell with two user-facing running modes: devlove and internet, with the first mode having some features and defaults 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 passive + active worker. Whenever a worker is started, it tries to bind a Unix Domain socket which is specific 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 successful 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 for a random amount of time decided at startup and 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 occasions when the master is killed with SIGKILL, so that the workers also exit without being prompted by their controller.

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 start 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 assumption 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.

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:

  • Normal unit testing for several of its components, used the most for components in charge of decoding and encoding data.

  • A suite of integration tests with 220 tests at the time of writing, and growing. These tests exercise the behavior of ShimmerCat as a complete system.

  • A growing suite of fuzz tests, which subject ShimmerCat to random combinations of faults in its environment and inputs and outputs.

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

  • The number of automatic tests should increase regularly, e.g. a few per developer per month.
  • Big changes in ShimmerCat need to pass all the automatic tests and be tested by hand, both locally and on production websites.

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.

Distribution policy and open source

We are a for-profit corporation, and we have a fiduciary responsibility towards our owners and investors, but in so far as it doesn't interferes with those responsibilities, we love and respect open source. What is more, our company's management has instigated our development team to make ShimmerCat QS open source. However, both our development team and our management recognize that our organization does not currently have the resources to reconcile good open source governance with our financial goals. If you would like that to change, join us. In the meantime, feel free to use both ShimmerCat QS and/or our accelerator distribution free of charge.

Licensing terms

ShimmerCat QS is copyright ShimmerCat AB, 2015, 2016, 2017, 2018 and 2019.

Unless a particular overriding agreement is subscribed between you and ShimmerCat AB, your use of ShimmerCat QS is governed by the following terms:

  • You understand that we may change these terms at any time. Your use of a particular version of ShimmerCat QS is governed by this terms (i.e., this section of this page) at the time you downloaded ShimmerCat QS from the link on the top of the page.
  • You may use ShimmerCat QS at your own risk: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.