= nng_surveyor(7)
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This document is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
// file was obtained (LICENSE.txt).  A copy of the license may also be
// found online at https://opensource.org/licenses/MIT.
//

== NAME

nng_surveyor - surveyor protocol

== SYNOPSIS

[source,c]
----
#include <nng/nng.h>
#include <nng/protocol/survey0/survey.h>
----

== DESCRIPTION

(((protocol, _surveyor_)))
The ((_surveyor_ protocol)) is one half of a ((survey pattern)).
In this pattern, a surveyor sends a survey, which is broadcast to all
peer respondents.
The respondents then have a chance to reply (but are not obliged to reply).
The survey itself is a timed event, so that responses
received after the survey has finished are discarded.

TIP: This protocol is useful in solving voting problems, such as
((leader election)) in cluster configurations, as well as certain kinds of
((service discovery)) problems.

The _surveyor_ protocol is the surveyor side, and the
xref:nng_respondent.7.adoc[_respondent_] protocol is the respondent side.

=== Socket Operations

The xref:nng_surveyor_open.3.adoc[`nng_surveyor0_open()`]
functions create a surveyor socket.
This socket may be used to send messages (surveys), and then to receive replies.
A reply can only be received after sending a survey.
A surveyor can normally expect to receive at most one reply from each responder.
(Messages can be duplicated in some topologies,
so there is no guarantee of this.)

Attempts to receive on a socket with no outstanding survey will result
in `NNG_ESTATE`.
If the survey times out while the surveyor is waiting
for replies, then the result will be `NNG_ETIMEDOUT`.

Only one survey can be outstanding at a time; sending another survey will
cancel the prior one, and any responses from respondents from the prior
survey that arrive after this will be discarded.

xref:nng.7.adoc#raw_mode[Raw] mode sockets ignore all these restrictions.

=== Context Operations

This protocol supports the creation of xref:nng_ctx.5.adoc[contexts] for concurrent
use cases using xref:nng_ctx_open.3.adoc[`nng_ctx_open()`].

Each context can initiate its own surveys, and it will receive only
responses to its own outstanding surveys.
Other contexts on the same socket may have overlapping surveys
operating at the same time.

Each of these may have their own timeouts established with
`NNG_OPT_SURVEYOR_SURVEYTIME`.

Additionally, sending a survey on a context will only cancel an outstanding
survey on the same context.

NOTE: Due to the best-effort nature of this protocol, if too may contexts
are attempting to perform surveys simultaneously, it is possible for either
individual outgoing surveys or incoming responses to be lost.

=== Protocol Versions

Only version 0 of this protocol is supported.
(At the time of writing, no other versions of this protocol have been defined.
An earlier and incompatible version of the protocol was used in older
pre-releases of
http://nanomsg.org[nanomsg], but was not released in any production
version.)

=== Protocol Options

The following protocol-specific options is available.

((`NNG_OPT_SURVEYOR_SURVEYTIME`))::

   (xref:nng_duration.5.adoc[`nng_duration`]) Duration of surveys.
   When a new survey is started, a timer of this duration is also started.
   Any responses arriving this time will be discarded.
   Attempts to receive
   after the timer expires with no other surveys started will result in
   `NNG_ESTATE`.
   Attempts to receive when this timer expires will result in `NNG_ETIMEDOUT`.

=== Protocol Headers

(((backtrace)))
This form uses a stack of 32-bit big-endian identifiers.
There *must* be at least one identifier, the __survey ID__, which will be the
last element in the array, and *must* have the most significant bit set.

There may be additional __peer ID__s preceding the survey ID.
These will be distinguishable from the survey ID by having their most
significant bit clear.

When a survey message is received by a forwarding node (see
xref:nng_device.3.adoc[`nng_device()`]), the forwarding node prepends a
32-bit peer ID (which *must* have the most significant bit clear),
which is the forwarder's way of identifying the directly connected
peer from which it received the message.
(This peer ID, except for the
most significant bit, has meaning only to the forwarding node itself.)

It may help to think of prepending a peer ID as pushing a peer ID onto the
front of the stack of headers for the message.
(It will use the peer ID
it popped from the front to determine the next intermediate destination
for the response.)

When a response message is created, it is created using the same headers
that the survey contained.

A forwarding node can pop the peer ID it originally pushed on the
message, stripping it from the front of the message as it does so.

When the response finally arrives back at the initiating surveyor, it
should have only a single element in the message, which will be the
survey ID it originally used for the request.

More detail can be found in the
https://github.com/nanomsg/nanomsg/blob/master/rfc/sp-surveyor-01.txt[RFC sp-surveyor-01]
document.

== SEE ALSO

[.text-left]
xref:nng_surveyor_open.3.adoc[nng_surveyor_open(3)],
xref:nng_respondent.7.adoc[nng_respondent(7)],
xref:nng.7.adoc[nng(7)]
