Search

The finite state machine

The finite state machine

As mentioned earlier, the VCL language allows you to extend the behavior of various Varnish states that are part of the Varnish finite state machine.

This probably makes sense to some extent, but without a visual representation, it is a tough concept to grasp.

Here’s the flowchart that describes the states and the state transitions of this finite state machine. The diagram below represents the interaction between a client and Varnish.

Varnish’s finite state machine on the client side

The client-side flow

It all starts when Varnish receives a request from a client. vcl_recv gets called, and depending on certain request criteria, a couple of different actions can be taken.

These actions control which path is taken through the finite state machine:

  • The vcl_recv, vcl_hash, vcl_hit, vcl_deliver path represents the desired outcome: a cache hit.
  • The vcl_recv, vcl_hash, vcl_miss, Backend fetch, vcl_deliver path represents an acceptable outcome: a cache miss.
  • The vcl_recv, vcl_hash, vcl_pass, Backend fetch, vcl_deliver path represents an undesirable outcome: bypassing the cache.
  • The vcl_recv, vcl_pipe path represents an escape plan: bypassing HTTP entirely and switching to TCP.
  • The vcl_recv, vcl_hash, vcl_purge, vcl_synth path represents a cache purge, which explicitly removes an object from cache.
  • The dotted lines represent potential transitions to return synthetic output at any point in time.

Remember: cache misses aren’t a bad thing. A miss is just a hit that didn’t happen yet.

There’s always the incoming request that triggers the start of the flow, but there must also be something that ends the transaction. In HTTP, we always expect a response to be returned.

From VCL, we can return(abandon), which will just drop the connection. This can be desirable in some cases but breaks the HTTP transaction, and that’s another story.

And that’s how the finite state machine ends the transaction: by delivering a response to the client. It could be a cached object, it could be a backend fetch, or it could just be synthetic output.

What you don’t see in this diagram is the backend flow. When there is a cache miss, or the cache is bypassed, you’ll need to connect to the origin and fetch the result. In this diagram, backend interaction was abstracted into a single backend-fetch state.

Let’s have a look at the backend flow in some more detail.

The backend flow

The backend flow represents the communication between Varnish and the origin server.

As you can see in the diagram below, the flow is a lot simpler compared to the client-side flow:

Varnish’s finite state machine on the backend side

In vcl_backend_fetch, the request to the backend is prepared, and the original client request is turned into a backend request.

Depending on what happens on the backend, you either end up in vcl_backend_response when the request is successfully processed, or in vcl_backend_error when an error occurs.

In vcl_backend_response a number of checks happen to decide whether or not to cache the response. Eventually the response is sent back to the client-side logic of Varnish, which will send the response to the client.

The vcl_backend_error stage is reached when Varnish fails to connect to a backend, when a backend is considered as sick, or when the backend doesn’t respond in time. You can also reach this stage from vcl_backend_fetch or vcl_backend_response by using a return(error) statement.

The result is that a synthetic error is returned and sent back to Varnish’s client-side logic with an HTTP 503 Service Unavailable error.

Surprisingly, other 500-range errors that were received from the backend aren’t considered errors. They can be cached, vcl_backend_error is not triggered, and the response is sent to the client without any interference from Varnish.

Whether you have a successful response, or an error, a backend response is returned, which in its turn will be sent to the client.


®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203