Names beginning with the character / are hierarchical paths in the
tradition of Unix. They denote an abstract location — i.e. what you
want. Path names must be bound by the current namespace in order to
identify where the network location(s) are.

A delegation table (or “dtab”) defines the namespace for a Finagle
transaction. A dtab comprises an ordered list of delegations which
together define how a path is interpreted. A delegation is a rewrite
rule src=>dest. When a name has src as a prefix, the prefix
is replaced with dest; otherwise the rule does not apply.
Delegations have the concrete syntax

src => dest

where src and dest are paths. As an example, the delegation

/s => /s#/foo/bar

rewrites the path

/s/crawler

to

/s#/foo/bar/crawler

Note that prefixes match on path components, not characters; e.g.
/s is a prefix of /s/crawler, but not of /s#/foo/bar/crawler.

Furthermore, prefixes may contain the wildcard character * to match
any component. For example

/s#/*/bar => /t/bah

rewrites the paths

/s#/foo/bar/baz

or

/s#/boo/bar/baz

to

/t/bah/baz

Paths beginning with /$/ are called “system paths.” They are interpreted
specially by Finagle, similarly to resolver schemes. Paths of the form

/$/namer/path..

uses the given Namer to interpret the
remaining path. This allows Finagle to translate paths into addresses. For
example

/$/inet/localhost/8080

is bound by Finagle to the Internet address localhost:8080. Similarly,

/$/com.twitter.serverset/zk.local.twitter.com:2181/foo/bar

is the path describing the serverset/foo/bar on the ZooKeeper
ensemble zk.local.twitter.com:2181.

Dtabs may contain line-oriented comments beginning with #. #
must be preceded by a whitespace character or delimiter such as ;,
|, or &. For example, this Dtab with commentary:

We use dtabs to define how logical names (e.g. /s/crawler)
translate into addresses. Because rewriting is abstracted away, we can
adapt a Finagle process to its environment by manipulating its dtab.
For example, this allows us to define /s/crawler to mean one set
of hosts when a process is running in a production setting, and
another set of hosts when developing or testing. A more complete
example follows.

We’ve turned the path /s/crawler into the serverset/prod/crawler
on zk.local.twitter.com:2181. We use the # character to denote
handlers — the path /s# “handles” /s and so on. To
see why this indirection is necessary, consider redefining /s by
adding a prefix — a common namespacing operation. The entry

/s => /s/prefix

would recurse; for example the name /s/crawler would be rewritten

/s/crawler
/s/prefix/crawler
/s/prefix/prefix/crawler
...

and so on. With /s#, we’d instead add

/s => /s#/prefix

to get the desired effect

/s/crawler
/s#/prefix/crawler
...

We can easily manipulate our Dtab to affect certain parts of the resolution.
For example, if we wanted to use staging instances of services instead of their
production ones, we’d append the delegation /s#=>/s##/staging making the
Dtab

Simply adding a new delegation is sufficient. Later entries are
attempted before earlier ones; if a rewrite rooted at a delegation
fails to produce an address, rewriting resumes from the next matching
delegation.

The combined effect is a fallback mechanism — if the
crawler exists in the staging environment, it is used; otherwise
we fall back to its production definition.

In the above example, if /staging/crawler did not exist on
zk.local.twitter.com:2181, the search would backtrack from (a),
producing the following set of rewrites:

We now see that delegations provide a simple and flexible means by
which to define a namespace. Its effect is similar to that of a Unix
mount table: Names stand on their own, but the minutiae of binding is
handled by the environment — i.e. the dtab.

Delegations are passed between servers if a supported protocol is
used. Thus a server alters the interpretation of names in the context
of the entire request graph, allowing a server to affect downstream
behavior for the current transaction. As an example a developer might
want to replace an individual component in a distributed system with a
development version of that component. This can be done by
orchestrating the originator (for example, an HTTP frontend) to add a
delegation expressing this override.

Finagle has protocol support for delegation passing in TTwitter, Mux, its variant ThriftMux, and HTTP. When these protocols are used,
delegations that are added dynamically to a request are in effect
throughout the distributed request graph — i.e. scope of the
namespace is a transaction. Delegations are added dynamically through
the Dtab API.