ETOOBUSY 🚀 minimal blogging for the impatient
xmpl - the "healthz" API
TL;DR
A closer look to the implementation of the “healthz” API in xmpl. This is a series of posts.
In applications that aim to be deployed in Kubernetes, it is often good to provide an endpoint that the external platform can call to figure out whether the application is feeling good or not. In case it does not… the system will figure out.
This interface does not need to be anything complicated: setting the
right HTTP status code suffices. In our case, we will provide back a
204
(No Content) when the health check is successful, and a 500
when it is not:
get '/healthz' => sub ($c) {
if (is_healthy()) { $c->rendered(204) }
else { $c->render(status => 500, text => "Internal Server Error\n") }
};
As we can see, the whole health check is encapsulated into a call to
function is_healthy
: depending on the outcome, we give back the
relevant HTTP status code.
But… we are in an example application that should be useful for testing, right? What if we want to test the outer platform, then?
It’s useful to be able to tell the application to always appear as
either healthy or unhealthy; for this reason, we can leverage the
endpoint for the PUT
verb:
put '/healthz' => sub ($c) {
is_healthy(($c->req->text // '') =~ s{\A\s+|\s+\z}{}grmxs);
$c->rendered(204);
};
This calls the same is_healthy
function, this time passing a
value (taken from the body by stripping leading and trailing spaces) to
set the desired output. This gives us a handle to externally control
what the GET
endpoint will respond back.
Now, of course, it’s time to take a look at is_healthy
:
sub is_healthy {
state $h;
$h = shift if @_;
defined($h) && length($h) ? $h : kvstore()->is_healthy;
}
It’s like a little singleton object with one single method, right? If
the value of the internal state ($h
) is set to a non-empty string,
then it will be used as a regular Perl boolean; otherwise, the
health of the key/value store will be assessed. This behaviour on an
empty string allows resetting the behaviour from the PUT
endpoint
(i.e. just pass an empty body in the HTTP PUT request).
Stay healthy!