/lancaster

Primary LanguageCGNU Lesser General Public License v3.0LGPL-3.0

# LANCASTER - fast, reliable multicasting of ephemeral data
# Copyright (c)2014-2017 Peak6 Investments, LP.  All rights reserved.

The software consists of a C library, liblancaster, provided in both static and
dynamic forms, together with nine utility programs for use in production and
development environments.

Any questions, bug reports, suggestions for improvements etc. - please email
the maintainers at bug-lancaster@peak6.com

             ===============================================

    writer [-v] [-L] [-p ERROR PREFIX] [-q CHANGE-QUEUE-CAPACITY] [-r] \
           [-T TOUCH-PERIOD] STORAGE-FILE DELAY

    reader [-v] [-L] [-O ORPHAN-TIMEOUT] [-p ERROR PREFIX] [-Q] [-R] [-s] \
           STORAGE-FILE

These are test programs which write and read data to/from a "storage" and check
whether what is read is what was written, in the correct order.

Storages are arrays of records, each having an identifier, contained within a
regular file on disk, such as "/tmp/my-file", or a POSIX shared memory segment,
which is specified with a URI-like prefix of shm, eg. "shm:/my-segment".
Storages can persist across runs.

A "change queue" is an optional section of a storage used as a circular buffer
containing the identifiers of records recently modified.  The capacity of a
change queue, if specified, must be either zero or a non-zero power of two.

WRITER will create a storage with a change queue of the given capacity, then
update sequential slots with ascending values at a speed determined by DELAY
(the number of microseconds to pause after each write, which may be zero).  If
the -r option is specified, slots will be chosen for update at random, instead
of sequentially.  The storage will be "touched" at least every TOUCH-PERIOD
microseconds (defaulting to one second).

READER outputs a hexadecimal digit every fifth of a second to indicate the
integrity of the read data - its value is the bitwise OR-ing of the following
numbers, indicating which conditions occured in this last "tick":-

    0 - no data was read
    1 - some data was read
    2 - some data was read, but it was delivered out of order
    4 - the change queue was overrun (only if -Q option is specified)

If the -s option is supplied to READER then it will output storage latency
statistics instead of its usual output.  If the storage has not been "touched"
by its writer for ORPHAN-TIMEOUT microseconds (defaulting to 3 seconds), READER
will exit with an error.  An ORPHAN-TIMEOUT of zero will disable this checking.
The -R option will cause READER to ignore the recreation (reopening) of the
storage (without this option, recreation causes READER to exit with an error).
The -Q option causes READER to ignore the change queue being overrun and simply
note the fact in its output, instead of exiting with an error.

The -p option causes the programs to include the specified prefix in error
messages, to allow easier identification when running multiple instances.

The -L option causes diagnostic messages to be prefixed with a timestamp,
suitable for outputing to a log file.

             ===============================================

    publisher [-v] [-a ADVERT-ADDRESS:PORT] [-A ADVERT-PERIOD] \
              [-e ENVIRONMENT] [-H HEARTBEAT-PERIOD] [-i DATA-INTERFACE] \
              [-I ADVERT-INTERFACE] [-j|-s] [-l] [-L] [-O ORPHAN-TIMEOUT] \
              [-p ERROR PREFIX] [-P MAXIMUM-PACKET-AGE] [-Q] [-R] \
              [-S STATISTICS-UDP-ADDRESS:PORT] [-t TTL] STORAGE-FILE \
              TCP-ADDRESS:PORT MULTICAST-ADDRESS:PORT

    subscriber [-v] [-H MAX-MISSED-HEARTBEATS] [-j] [-L] [-p ERROR PREFIX] \
               [-q CHANGE-QUEUE-CAPACITY] [-S STATISTICS-UDP-ADDRESS:PORT] \
               [-T TOUCH-PERIOD] STORAGE-FILE TCP-ADDRESS:PORT

These are production-ready, generic programs to establish a multicast transport
between a process wanting to publish data and one or more processes on multiple
hosts wanting to receive it.

PUBLISHER looks for a storage to read from (such as one created by WRITER).  It
will listen on TCP-ADDRESS:PORT for connections from subscribers.  When one is
made, PUBLISHER will send the subscriber the MULTICAST-ADDRESS:PORT to receive
data, and the HEARTBEAT-PERIOD microseconds (defaulting to one second) it
should expect to receive heartbeats in the absence of data (PUBLISHER will send
separate heartbeats over both the TCP and multicast channels.  If a heartbeat
is not received in time, SUBSCRIBER will exit with an error.)  PUBLISHER will
attempt to fill a UDP packet with data before sending it, but will send a
partial packet if the data in it is older than MAX-PACKET-AGE microseconds
(defaulting to 2 milliseconds).  PUBLISHER will multicast data over the
DATA-INTERFACE network interface rather than the system's default, if the -i
option is specified.  Multicast data will be sent with a TTL other than 1 if
the -t option is specified.  Multicast data will "loopback" (be delivered also
on the sending host) if the -l option is specified, which enables testing on a
single host.  If the -a option is specified, PUBLISHER will "advertize" its
existence by multicasting its connection and storage details every
ADVERT-PERIOD microseconds (defaulting to 10 seconds).  Those advertisements
will be multicast over the ADVERT-INTERFACE network interface if the -I option
is specified, or the system's default if not.  If the storage has not been
recently "touched" by its writer within ORPHAN-TIMEOUT microseconds (defaulting
to 3 seconds), then PUBLISHER will exit with an error.  An ORPHAN-TIMEOUT of
zero will disable this checking.  The -R option will cause PUBLISHER to ignore
the recreation (reopening) of the storage by its writer (without this option,
recreation causes PUBLISHER to exit with an error).  The -Q option will cause
PUBLISHER to ignore overruns of the change queue, instead of exiting with an
error.

SUBSCRIBER will try to connect to a PUBLISHER at TCP-ADDRESS:PORT, and based on
the attributes that PUBLISHER sends it, create a storage similar in structure
to PUBLISHER's (except for the change queue capacity, which may be specified
for SUBSCRIBER independently, with the -q option).  Data read by PUBLISHER is
multicast to SUBSCRIBER and written to SUBSCRIBER's storage.  SUBSCRIBER will
"touch" the storage every TOUCH-PERIOD microseconds (defaulting to one second).
A TOUCH-PERIOD of zero will disable "touching".  SUBSCRIBER will expect to
receive regular heartbeats from PUBLISHER and will exit with an error if more
than MAX-MISSED-HEARTBEATS are not received, as configurable by the -H option
(the default value is 5 heartbeats).

Both PUBLISHER and SUBSCRIBER have an -j option which causes their normal
output of statistics to be output in JSON format.  The UDP address and port to
send statistics to, if any, is specified by the -S option.PUBLISHER also has an
-s option which causes it to output storage latency statistics instead of its
usual output (the -j option also includes the storage latency statistics).

A typical scenario for testing would be to run WRITER and PUBLISHER on one
host, and SUBSCRIBER and READER on another.  For example, if the former were to
be run on pslchi6dpricedev45 (10.2.2.152):-

    dev45$ writer -q 4096 /tmp/his-local-file 1000 &
    dev45$ publisher /tmp/his-local-file 10.2.2.152:23266 227.1.1.34:56134

...and the SUBSCRIBER and READER commands on pslchi6dpricedev42:-

    dev42$ subscriber shm:/her-local-segment 10.2.2.152:23266 &
    dev42$ reader shm:/her-local-segment

             ===============================================

    inspector [-v] [-a] [-L] [-p] [-q] [-r] [-V] STORAGE-FILE [RECORD-ID...]

    grower [-v] [-L] STORAGE-FILE NEW-STORAGE-FILE NEW-BASE-ID NEW-MAX-ID \
           NEW-VALUE-SIZE NEW-PROPERTY-SIZE NEW-QUEUE-CAPACITY

    deleter [-v] [-f] [-L] STORAGE-FILE [STORAGE-FILE ...]

These are utility programs to show, modify or delete a storage.

INSPECTOR, given the -a option, outputs the attribute values of a storage, such
as the size of a record within it, the capacity of its change queue, the
description associated with it, etc.  The -q option will cause the change
queue, if any, to be output, while the -r option will cause the timestamp and
revision of the specified records to be output - for all records, if no record
identifier(s) are specified).  Properties for records will be included in the
output if the -p option is given.  If no option is specified, the program will
only attempt to open and verify the storage, exiting with zero (success) if the
format of the storage is valid.

The GROWER program will create a new storage based upon an existing storage,
and containing the same data copied to its records (as applicable).  Any
attribute of the old storage can be carried over unchanged to the new storage,
by specifying "=" for it.  For example, to create a new storage "new-store"
that is identical to the existing "old-store", except for having a change queue
capacity of 1024 records:-

    dev45$ grower old-store new-store = = = = 1024

Expanding or contracting a storage can be done by specifying different values
for the base and maximum identifiers.  A straight copy of a storage can be done
by specifying "=" for all attributes.  NB. GROWER never copies the contents of
the change queue.

The DELETER program will delete the given storages.  If the -f option is given
then it is not an error if a storage does not exist.

             ===============================================

    eraser [-v] [-c] [-L] [-V] STORAGE-FILE RECORD-ID [RECORD-ID ...]

    copier [-v] [-L] [-V] SOURCE-STORAGE-FILE DESTINATION-STORAGE-FILE \
           SOURCE-RECORD-ID [SOURCE-RECORD-ID ...]

These are utility programs to modify the contents of storages.

ERASER removes the specified records from the specified storage.  The storage
is compacted to eliminate the holes left behind if the -c option is given.
(The compaction is performed by moving the last record in the storage to the
place where the erased record used to be).

COPIER makes a copy of the specified source record in the destination storage.

Each program, if the -V option is specified ("verbose"), will output the
identifiers of the records it is operating upon.

             ===============================================

Exit statuses: the programs will return a unique value for each kind of error
that causes them to quit.  The meaning of the various values is as follows:-

        0 - no error
    1-127 - C library error (error numbers as per errno.h)
  128-192 - terminated by a signal (128 + the signal number, given by kill -l)
  200-205 - C library error (error numbers as per errno.h, after subtracting 70)
  220-255 - Lancaster library error (as per status.h, after negating)