# pub_sub #
A simple tcp based publisher/subscriber.

## Basic ideas ##
 * Provide a simple interface for streaming data where the
 application has a straight forward way to provide a
 monotonically increasing key identifying each message.
 
 * IO is performed on background threads asynchronously.
 
 * Applications/users do not need to handle and manage
 individual connections.
 
 * This is modeled as a simple zmq like system.

 * This is written for possible use in streaming data in
 CDS.
 
 ## Implementation ##
 * C++14 or greater
 * Boost::asio for the networking (this is not exposed
 in the api)

## Examples and Notes ##
 A simple publisher is found in:
  * examples/publisher.cc
 
 A simple subscriber is found in:
  * examples/subscriber.cc
  
 The protocol is loosely described in:
  * pub_sub/private/pub_sub_intl.hh
 
 The main includes are:
  * pub_sub/include/pub_sub/common.hh
  * pub_sub/include/pub_sub/pub.hh
  * pub_sub/include/pub_sub/sub.hh

## Slow consumers ##
Publishers keep a bounded history of recently published messages so
that tcp subscribers can catch up if they briefly fall behind.  A
subscriber that falls behind the retained history is a *slow consumer*
and is skipped ahead: it will see a gap in the message keys and then
resume with the oldest retained message.  Publishers never buffer an
unbounded amount of data for a slow consumer.

The history depth is set by the `PUBLISHER_MAX_DEPTH` environment
variable (read once when a Publisher is created): the number of
messages retained per destination, an integer in the range 3-60.
Invalid values are ignored with a warning and the default of 8 is
used.

The `PubDebugNotices::slow_client_detected` hook is called whenever a
slow consumer is skipped ahead.

### Per-destination options in the connection string ###
The built-in publisher transports also accept options as URL style
query parameters on their pipeline stage:

    tcp://127.0.0.1:9000?max_depth=16
    zstd://3|tcp://127.0.0.1:9000?max_depth=16
    multi://127.0.0.1/239.192.0.1:9000?max_depth=40

 * Precedence is connection string > environment > built-in default,
 so different destinations of one Publisher can use different values.
 * `max_depth` takes an integer in 3-60.
 * Unlike the environment, invalid values, unknown keys, and
 duplicated keys in a connection string throw from
 `Publisher::add_destination` — the connection cannot be made.

Custom plugins receive the raw stage string as before; the helper the
built-in transports use to split a stage into scheme, path, and
arguments is public (`cds-pubsub/stage_address.hh`,
`pub_sub::parse_stage_address`) so plugins can adopt the same
convention.

## License ##
GPL 3.  See COPYING.

The code under external/catch2 is licensed under the Boost license.
See the external/LICENSE_1_0.txt for the license. 
  
  