Finicky Whiskers (pt. 1): The World's Most Adorable Manual Load Generator
Matt Butcher
finicky whiskers
webassembly
microservices
rust
golang
ruby
Slats the cat is hungry.
But the thing is, she can never decide on just one food.
At one moment, she craves fish.
A moment later, only fresh veggies will do.
Then chicken alone can satisfy her discerning palette… nevermind.
She’s back to fish.
That is the premise behind Finicky Whiskers, Fermyon’s fast-paced game of feline fickleness.
But behind this adorable feline is an architecture designed
to showcase why Fermyon is excited about WebAssembly as the next wave of cloud compute.
We first unveiled Finicky Whiskers at DockerCon 2022 during the session WebAssembly and Containers (video). In this series, we’ll go into more depth about how Finicky Whiskers works.
Playing the Game
The game mechanic for Finicky Whiskers goes like this:
- Slats’ current craving is depicted in a thought bubble hovering near her head.
- The icon in the thought bubble matches one of the four icons on the yellow buttons at the bottom of the game.
- Chicken, fish, beef, and veggies are each enticing treats (at least for a moment) for the ever-discerning Slats.
As the thirty second timer ticks down, Slats changes her mind every few seconds.
First it’s fish.
Then perhaps beef.
Your job is simple: Fulfill her whim by repeatedly clicking on the button for the desired flavor.
The more times you feed her what she wants, the higher your score.
Can you feed Slats enough food to satisfy her before time expires?
The Wasm Behind Slats
As cute as Slats is, we do not believe she’s the true star of this show.
The stars are the WebAssembly components running behind the scenes.
Finicky Whiskers is not only a cute game, but a demonstration of microservices rethought.
A game of Finicky Whiskers sends hundreds of requests to the cloud,
where a Spin server listens for requests and executes WebAssembly components.
In fact, Finicky Whiskers is composed of several microservices, all running as WebAssembly components in Spin.
The main ones are:
- The fileserver that sends the HTML, images, CSS, and other assets that paint that cute little cat in your browser
- The session manager that starts the game and keeps track of both the timer and Slats’ ever-changing preferences
- The food tally that registers each click, verifies it, and sends an event to a Redis queue
- The morsel score keeper that reads from the Redis queue and grants points based on whether you fed Slats the right thing
- The scoreboard that shows your score at the end
Five separate microservices!
That’s what it takes to feed Slats the cat.
And as we’ll see in this series, microservices are written in a variety of languages using a variety of services.
Some are HTTP listeners.
Others wait for events on a Redis queue.
A few services are written in Rust.
Others use Go or Ruby.
All of these things combine to show you why we are excited about Spin’s potential as a next-wave cloud runtime.
The World’s Most Adorable Load Generator
Now, before we get into the details, an experienced game developer might point out that
if we were optimizing for performance, we wouldn’t be making so many round-trips to the server.
This is very true.
But we’re not trying to minimize traffic to the server.
We’re trying to maximize it.
Because what we set out to show with Finicky Whiskers is that WebAssembly is fast, scalable, and tolerant to high loads.
In other words, we built a game with the intention of generating server load.
And you, Player One, are the load generator.
The faster you click, the more load the Fermyon Spin instances receive.
With each click, a few more WebAssembly instances are started, run to completion, and then shut down.
In a typical game, a player will invoke in excess of 200 separate WebAssembly components.
And with Spin’s scale-to-zero architecture,
we are starting, running, and tearing down each module for each request.
Finicky Whiskers is the world’s most adorable manual load generator.
This has some cool implications.
When nobody is playing Finicky Whiskers, no WebAssembly components are running.
When a few dozen people are playing, our Nomad cluster is invoking potentially thousands of components.
The Fermyon.com website runs a similar setup.
With only a few t2.small
workers on AWS, our Nomad cluster has fielded thousands of concurrent requests–invoking thousands of WebAssembly components–without breaking a sweat.
(Thank you, HackerNews folks! You were the original manual load generators!)
Finicky whiskers ups the ante.
A game session generates a decent amount of load.
The more players, the more load.
As you play, we learn about how resilient Spin is under production-grade load.
The Series: Learning About Finicky Whiskers
How does Finicky Whiskers work?
That’s the subject of this series.
In each of the remaining parts, we’ll take a look at a couple of the Finicky Whiskers microservices,
learning about how each one was written, what it does, and how it cooperates with the other services.
We’ll also take a peak at the infrastructure that runs Finicky Whiskers,
where we’ll see Docker containers and a Nomad cluster doing some of the work.
By the end of the series, you’ll know the deep dark secrets of Slat’s food desires.
So tune in for our next installment, as we look at the fileserver module that services Finicky Whiskers’
static assets.
Read Next
Finicky Whiskers (pt. 2): “Serving the HTML, CSS, and static assets.”