The Mount Table
Wherein you use the basic tools of service discovery.
Prerequisites:
All tutorials require Vanadium installation, and must run in a bash shell.
Further, please download this script then source it:
source ~/Downloads/scenario-b-setup.sh
This command wipes tutorial files and defines shell environment variables. If you start a new terminal, and just want to re-establish the environment, see instructions here.
Introduction
This tutorial focusses on using a mount table with the fortune server and client programs you made in the basics tutorial, and just re-made with the prerequisites script above.
Credentials
To keep security simple initially, all processes here will use the same credentials. Further, credentials will be specified using this environment variable:
export V23_CREDENTIALS=$V_TUT/cred/basics
Vanadium programs consult this environment variable when the
credentials aren't specified by using the --v23.credentials
flag,
or by using a security agent.
Start a table
When you ran the fortune server in the basics tutorial, you told it to write its network endpoint to a file, then you told the client to read that file so it would know where to find the server.
Let's do that again, but this time instead of using a file to hold the endpoint, we'll use a server.
The server is called a mount table, and its executable has the name
mounttabled
:
PORT_MT=23000 # Pick an unused port.
kill_tut_process TUT_PID_MT
$V_BIN/mounttabled --v23.tcp.address :$PORT_MT &
TUT_PID_MT=$!
A mount table happens to be a Vanadium service. This means the vrpc program can report its VDL interface:
$V_BIN/vrpc signature -s /localhost:$PORT_MT
It also means that the mount table has a principal - it must run
with credentials. Since the --v23.credentials
flag wasn't
specified at startup, the Vanadium runtime consulted the environment
variable V23_CREDENTIALS
(set above) to get the credentials.
Had credentials been left unspecified, randomly generated credentials would have been used, and the problems reviewed at the end of the basics tutorial would happen below when processes start talking to each other. Mount table security will be discussed in later tutorial.
The -s
option stands for 'shallow resolve'. It forces vprc to apply
to mount table itself and not what might be mounted at its root.
The namespace client
The table is up, but empty.
Start the existing fortune server binary, so we have a service to put in the table:
kill_tut_process TUT_PID_S1
$V_TUT/bin/server --endpoint-file-name $V_TUT/s1.txt &
TUT_PID_S1=$!
Mounting
namespace
is a command line client dedicated to manipulating mount
tables. The following mounts the server at the name fortuneAlpha
.
$V_BIN/namespace \
--v23.namespace.root /localhost:$PORT_MT \
mount fortuneAlpha `cat $V_TUT/s1.txt` 100m
The flag --v23.namespace.root
specifies which mount table to
use. The flag is available in all Vanadium programs.
In Vanadium, services live in hierachical trees called the namespaces. The root node of a tree is a mount table, hence the flag name. Other nodes are either services (leaves) or other mount tables.
Globbing
To glob is to use a character pattern to select strings from a set.
The command namespace glob *
reports the names of all known
names:
$V_BIN/namespace \
--v23.namespace.root /localhost:$PORT_MT \
glob -l '*'
There's just one name: fortuneAlpha
. Use of the flag -l
triggers additional output; you see the name's endpoint,
and you see it will expire (will be dropped from the table) in
about one hundred minutes. That's what the 100m
meant in the
mount
command above.
Resolution
When a name is known, and you just want to resolve it to an
endpoint, use namespace resolve {name}
:
$V_BIN/namespace \
--v23.namespace.root /localhost:$PORT_MT \
resolve fortuneAlpha
The output should match the endpoint recorded in $V_TUT/s1.txt
:
cat $V_TUT/s1.txt
Name usage
Recapping, here's how you connected the fortune client to the fortune server using a full service endpoint name in the basics tutorial:
$V_TUT/bin/client --server `cat $V_TUT/s1.txt`
Now you can use the name fortuneAlpha
instead:
$V_TUT/bin/client \
--v23.namespace.root /localhost:$PORT_MT \
--server fortuneAlpha
The client
program didn't need to be recompiled to allow this new
usage because Vanadium code in the client interprets the value
of the --server
flag.
In the first command, --server
's value was something like
/@3@tcp@127.0.0.1:...
. The leading /
caused it to be interpreted
directly as an endpoint rather than as a service name to be used as
a lookup key. That means communication attempts begin immediately,
and if the string doesn't refer to a live service, you won't know it
until the attempts timeout.
In the second command, --server
's value was just fortuneAlpha
.
Strings that don't start with /
are treated as service names needing
a lookup. If a lookup fails, the client will know it immediately, and
may retry depending on various configurations.
The namespace variable
This tutorial uses only one mount table, and it's repetitive to
constantly specify the --v23.namespace.root
flag with the same
value.
Ommiting the flag will trigger use the following shell variable:
export V23_NAMESPACE=/localhost:$PORT_MT
Now a fortune retrieval is as simple as:
$V_TUT/bin/client --server fortuneAlpha
Flags vs. variables
In Vanadium, flag values, when specified, always trump the values of
corresponding shell variables. So --v23.namespace.root
trumps
$V23_NAMESPACE
, and --v23.credentials
trumps $V23_CREDENTIALS
.
Shell variable values, in turn, trump default behavior.
The default behavior for unspecified namespace is to use a public
mount table maintained by the v23 team. Circa April 2015 the service
runs at ns.dev.v.io:8101
. The port serves Vanadium protocol, not
HTTP.
The default behavior for unspecified credentials is to generate random credentials.
Many names, one endpoint
A single service instance can have multiple names. Mount the same
service again, with the name fortuneBeta
, and a brief time to live:
$V_BIN/namespace mount fortuneBeta `cat $V_TUT/s1.txt` 5m
Do the glob
again:
$V_BIN/namespace glob -l '*'
You'll see two names, with the same endpoint, but with different expiration times. Later you'll find the names can have different access control lists as well.
Confirm that the second name works:
$V_TUT/bin/client --server fortuneBeta
Many endpoints, one name
Start a second instance of the fortune server:
kill_tut_process TUT_PID_S2
$V_TUT/bin/server --endpoint-file-name $V_TUT/s2.txt &
TUT_PID_S2=$!
Mount it on the (original) name fortuneAlpha
:
$V_BIN/namespace mount fortuneAlpha `cat $V_TUT/s2.txt` 100m
List the names again:
$V_BIN/namespace glob -l '*'
Now the name fortuneAlpha
reports two endpoints, with distinct
expiration times.
This is a means to implement redundancy, load sharing, etc. The mount table will resolve specific requests to one endpoint, but multiple endpoints let it assign a server using simple rotation, or by using load, response times, etc.
Confirm that fortuneAlpha
still works (with two endpoints):
$V_TUT/bin/client --server fortuneAlpha
Now kill the original server:
kill_tut_process TUT_PID_S1
And retry the request:
$V_TUT/bin/client --server fortuneAlpha
You should still get a fortune, but this time it can only come from the second server instance.
The mount table will still report the dangling endpoint until it expires, as it might come back to life.
Unmounting
Unmounting works as you might expect:
$V_BIN/namespace unmount fortuneAlpha `cat $V_TUT/s1.txt`
$V_BIN/namespace unmount fortuneBeta `cat $V_TUT/s1.txt`
That leaves only server 2 in the table (with the name fortuneAlpha
):
$V_BIN/namespace glob -l '*'
The reported endpoint should match the stored endpoint of server 2:
cat $V_TUT/s2.txt
Unmount it as well:
$V_BIN/namespace unmount fortuneAlpha `cat $V_TUT/s2.txt`
Optionally observe failure
Optionally, confirm that client use of the unmounted name fortuneAlpha
fails.
Feel free to interrupt before the retry attempts exhaust themselves.
$V_TUT/bin/client --server fortuneAlpha
Cleanup
kill_tut_process TUT_PID_S2
kill_tut_process TUT_PID_MT
unset V23_CREDENTIALS
unset V23_NAMESPACE
Summary
A service called
mounttabled
is a Vanadium service that helps Vanadium services find each other.The command-line client
namespace
performs general operations on an instance ofmounttabled
.The shell variables
$V23_CREDENTIALS
and$V23_NAMESPACE
can be used instead of flags to configure a Vanadium program.