## Surveyor Protocol (_SURVEYOR_)

The ((_SURVEYOR_ protocol))(((protocol, _SURVEYOR_))) 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.

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

The _SURVEYOR_ protocol is the surveyor side, and the xref:respondent.adoc[_RESPONDENT_] protocol is the respondent side.

### Socket Operations

The xref:nng_surveyor_open.adoc[`nng_surveyor_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:../sock/raw.adoc[Raw mode] sockets ignore all these restrictions.

### Context Operations

This protocol supports the creation of xref:../ctx/index.adoc[contexts] for concurrent
use cases using xref:../ctx/nng_ctx_open.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.footnote:[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.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.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.
