File: //proc/thread-self/root/usr/share/doc/varnish-6.0.3/html/reference/directors.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Writing a Director — Varnish version 6.0.3 documentation</title>
<link rel="stylesheet" href="../_static/classic.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="varnish-counters" href="varnish-counters.html" />
<link rel="prev" title="vmod_std" href="vmod_generated.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="varnish-counters.html" title="varnish-counters"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="vmod_generated.html" title="vmod_std"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Varnish version 6.0.3 documentation</a> »</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">The Varnish Reference Manual</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="writing-a-director">
<span id="ref-writing-a-director"></span><h1>Writing a Director<a class="headerlink" href="#writing-a-director" title="Permalink to this headline">¶</a></h1>
<p>Varnish already provides a set of general-purpose directors, and since Varnish
4, it is bundled in the built-in <a class="reference internal" href="vmod_generated.html#vmod-directors-3"><span class="std std-ref">vmod_directors</span></a>. Writing a director
boils down to writing a VMOD, using the proper data structures and APIs. Not
only can you write your own director if none of the built-ins fit your needs,
but since Varnish 4.1 you can even write your own backends.</p>
<p>Backends can be categorized as such:</p>
<ul class="simple">
<li>static: native backends declared in VCL</li>
<li>dynamic: native backends created by VMODs</li>
<li>custom: backends created and fully managed by VMODs</li>
</ul>
<div class="section" id="backends-vs-directors">
<h2>Backends vs Directors<a class="headerlink" href="#backends-vs-directors" title="Permalink to this headline">¶</a></h2>
<p>The intuitive classification for backend and director is an endpoint for the
former and a cluster for the latter, but the actual implementation is a bit
more subtle. VMODs can accept backend arguments and return backends in VCL (see
<a class="reference internal" href="vmod.html#ref-vmod-vcl-c-types"><span class="std std-ref">VCL and C data types</span></a>), but the underlying C type is <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">director</span></code>.
Under the hood director is a generic concept, and a backend is a kind of
director.</p>
<p>The line between the two is somewhat blurry at this point, let’s look at some
code instead:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">struct</span> <span class="n">director</span> <span class="p">{</span>
<span class="n">unsigned</span> <span class="n">magic</span><span class="p">;</span>
<span class="c1">#define DIRECTOR_MAGIC 0x3336351d</span>
<span class="n">const</span> <span class="n">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span>
<span class="n">char</span> <span class="o">*</span><span class="n">vcl_name</span><span class="p">;</span>
<span class="n">vdi_http1pipe_f</span> <span class="o">*</span><span class="n">http1pipe</span><span class="p">;</span>
<span class="n">vdi_healthy_f</span> <span class="o">*</span><span class="n">healthy</span><span class="p">;</span>
<span class="n">vdi_resolve_f</span> <span class="o">*</span><span class="n">resolve</span><span class="p">;</span>
<span class="n">vdi_gethdrs_f</span> <span class="o">*</span><span class="n">gethdrs</span><span class="p">;</span>
<span class="n">vdi_getbody_f</span> <span class="o">*</span><span class="n">getbody</span><span class="p">;</span>
<span class="n">vdi_getip_f</span> <span class="o">*</span><span class="n">getip</span><span class="p">;</span>
<span class="n">vdi_finish_f</span> <span class="o">*</span><span class="n">finish</span><span class="p">;</span>
<span class="n">vdi_panic_f</span> <span class="o">*</span><span class="n">panic</span><span class="p">;</span>
<span class="n">void</span> <span class="o">*</span><span class="n">priv</span><span class="p">;</span>
<span class="n">const</span> <span class="n">void</span> <span class="o">*</span><span class="n">priv2</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>A director can be summed up as:</p>
<ul class="simple">
<li>a name (used for panics)</li>
<li>a VCL name</li>
<li>a set of operations</li>
<li>the associated state</li>
</ul>
<p>The difference between a <em>cluster</em> director and a <em>backend</em> director is mainly
The functions they will implement.</p>
</div>
<div class="section" id="cluster-directors">
<h2>Cluster Directors<a class="headerlink" href="#cluster-directors" title="Permalink to this headline">¶</a></h2>
<p>As in <a class="reference internal" href="vmod_generated.html#vmod-directors-3"><span class="std std-ref">vmod_directors</span></a>, you can write directors that will group
backends sharing the same role, and pick them according to a strategy. If you
need more than the built-in strategies (round-robin, hash, …), even though
they can be stacked, it is always possible to write your own.</p>
<p>In this case you simply need to implement the <code class="docutils literal notranslate"><span class="pre">resolve</span></code> function for the
director. Directors are walked until a leaf director is found. A leaf director
doesn’t have a <code class="docutils literal notranslate"><span class="pre">resolve</span></code> function and is used to actually make the backend
request, just like the backends you declare in VCL.</p>
</div>
<div class="section" id="dynamic-backends">
<h2>Dynamic Backends<a class="headerlink" href="#dynamic-backends" title="Permalink to this headline">¶</a></h2>
<p>If you want to speak HTTP/1 over TCP, but for some reason VCL does not fit the
bill, you can instead reuse the whole backend facility. It allows you for
instance to add and remove backends on-demand without the need to reload your
VCL. You can then leverage your provisioning system.</p>
<p>Consider the following snippet:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">backend</span> <span class="n">default</span> <span class="p">{</span>
<span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The VCL compiler turns this declaration into a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">vrt_backend</span></code>. When the
VCL is loaded, Varnish calls <code class="docutils literal notranslate"><span class="pre">VRT_new_backend</span></code> in order to create the
director. Varnish doesn’t expose its data structure for actual backends, only
the director abstraction and dynamic backends are built just like static
backends, one <em>struct</em> at a time. You can get rid of the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">vrt_backend</span></code>
as soon as you have the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">director</span></code>.</p>
<p>A (dynamic) backend can’t exceed its VCL’s lifespan, because native backends
are <em>owned</em> by VCLs. Though a dynamic backend can’t outlive its VCL, it can be
deleted any time with <code class="docutils literal notranslate"><span class="pre">VRT_delete_backend</span></code>. The VCL will delete the remaining
backends once discarded, you don’t need to take care of it.</p>
<p>Consider using an object to manipulate dynamic
backends. They are tied to the VCL life cycle and make a handy data structure
to keep track of backends and objects have a VCL name you can reuse for the
director. It is also true for <em>cluster</em> directors that may reference native
backends.</p>
<p>Finally, Varnish will take care of event propagation for <em>all</em> native backends,
but dynamic backends can only be created when the VCL is warm. If your backends
are created by an independent thread (basically outside of VCL scope) you must
subscribe to VCL events and watch for VCL state (see
<a class="reference internal" href="vmod.html#ref-vmod-event-functions"><span class="std std-ref">Event functions</span></a>). Varnish will panic if you try to create a
backend on a cold VCL, and <code class="docutils literal notranslate"><span class="pre">VRT_new_backend</span></code> will return <code class="docutils literal notranslate"><span class="pre">NULL</span></code> if the VCL
is cooling. You are also encouraged to comply with the
<a class="reference internal" href="varnish-cli.html#ref-vcl-temperature"><span class="std std-ref">VCL Temperature</span></a> in general.</p>
</div>
<div class="section" id="health-probes">
<span id="ref-writing-a-director-cluster"></span><h2>Health Probes<a class="headerlink" href="#health-probes" title="Permalink to this headline">¶</a></h2>
<p>It is possible in a VCL program to query the health of a director (see
<a class="reference internal" href="vmod_generated.html#func-healthy"><span class="std std-ref">BOOL healthy(BACKEND be)</span></a>). A director can report its health if it implements the
<code class="docutils literal notranslate"><span class="pre">healthy</span></code> function, it is otherwise always considered healthy.</p>
<p>Unless you are making a dynamic backend, you need to take care of the health
probes yourselves. For <em>cluster</em> directors, being healthy typically means
having at least one healthy underlying backend or director.</p>
<p>For dynamic backends, it is just a matter of assigning the <code class="docutils literal notranslate"><span class="pre">probe</span></code> field in
the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">vrt_backend</span></code>. Once the director is created, the probe definition
too is no longer needed. It is then Varnish that will take care of the health
probe and disable the feature on a cold VCL (see
<a class="reference internal" href="vmod.html#ref-vmod-event-functions"><span class="std std-ref">Event functions</span></a>).</p>
<p>Instead of initializing your own probe definition, you can get a <code class="docutils literal notranslate"><span class="pre">VCL_PROBE</span></code>
directly built from VCL (see <a class="reference internal" href="vmod.html#ref-vmod-vcl-c-types"><span class="std std-ref">VCL and C data types</span></a>).</p>
<p>What’s the difference ?</p>
</div>
<div class="section" id="custom-backends">
<h2>Custom Backends<a class="headerlink" href="#custom-backends" title="Permalink to this headline">¶</a></h2>
<p>If you want to implement a custom backend, have a look at how Varnish
implements native backends. It is the canonical implementation, and though it
provides other services like connection pooling or statistics, it is
essentially a director which state is a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">backend</span></code>. Varnish native
backends currently speak HTTP/1 over TCP, and as such, you need to make your
own custom backend if you want Varnish to do otherwise such as connect over
UDP or UNIX-domain sockets or speak a different protocol.</p>
<p>If you want to leverage probes declarations in VCL, which have the advantage of
being reusable since they are only specifications, you can. However, you need
to implement the whole probing infrastructure from scratch.</p>
<p>You may also consider making your custom backend compliant with regards to the
VCL state (see <a class="reference internal" href="vmod.html#ref-vmod-event-functions"><span class="std std-ref">Event functions</span></a>).</p>
<div class="section" id="data-structure-considerations">
<h3>Data structure considerations<a class="headerlink" href="#data-structure-considerations" title="Permalink to this headline">¶</a></h3>
<p>When you are creating a custom backend, you may want to provide the semantics
of the native backends. In this case, instead of repeating the redundant fields
between data structures, you can use the macros <code class="docutils literal notranslate"><span class="pre">VRT_BACKEND_FIELDS</span></code> and
<code class="docutils literal notranslate"><span class="pre">VRT_BACKEND_PROBE_FIELDS</span></code> to declare them all at once. This is the little
dance Varnish uses to copy data between the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">vrt_backend</span></code> and its
internal data structure for example.</p>
<p>The copy can be automated with the macros <code class="docutils literal notranslate"><span class="pre">VRT_BACKEND_HANDLE</span></code> and
<code class="docutils literal notranslate"><span class="pre">VRT_BACKEND_PROBE_HANDLE</span></code>. You can look at how they can be used in the
Varnish code base.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Writing a Director</a><ul>
<li><a class="reference internal" href="#backends-vs-directors">Backends vs Directors</a></li>
<li><a class="reference internal" href="#cluster-directors">Cluster Directors</a></li>
<li><a class="reference internal" href="#dynamic-backends">Dynamic Backends</a></li>
<li><a class="reference internal" href="#health-probes">Health Probes</a></li>
<li><a class="reference internal" href="#custom-backends">Custom Backends</a><ul>
<li><a class="reference internal" href="#data-structure-considerations">Data structure considerations</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="vmod_generated.html"
title="previous chapter">vmod_std</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="varnish-counters.html"
title="next chapter">varnish-counters</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/directors.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="varnish-counters.html" title="varnish-counters"
>next</a> |</li>
<li class="right" >
<a href="vmod_generated.html" title="vmod_std"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Varnish version 6.0.3 documentation</a> »</li>
<li class="nav-item nav-item-1"><a href="index.html" >The Varnish Reference Manual</a> »</li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2010-2014, Varnish Software AS.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
</div>
</body>
</html>