Data Source

The low-level API through which a pvxs::server::Server may issue requests on behalf of remote clients.

#include <pvxs/server.h>
namespace pvxs { namespace server { ... } }

The pvxs::server::SharedPV API should be preferred when a Server has a predetermined set of PV names.

The pvxs::server::Source interface is a more general, and complex, means of allowing a Server to respond to PV names as clients search for them. This may be necessary in specialized cases such as gateway, proxy, or bridge servers.

Threading

A Server will invoke user callback functions from one or more internal worker threads. However, it is guaranteed that callbacks relating to a given PV will never be executed concurrently. This implies that callbacks for a single operation, those stored through a pvxs::server::ChannelControl and related *Op, will also never be executed concurrently.

Ownership and Lifetime

The *Op classes are interfaces through which callback functors are passed. These functors are stored in underlying, and otherwise hidden, server data structures. Therefore, it is safe to eg. capture a shared_ptr<ExecOp> into an onCancel functor without creating a reference loop.

The lifetime of these server data structures are tied to the remote client. So variables captured into a functor like pvxs::server::ConnectOp::onGet(), or onCancel, will be destroyed when the client times out, closes the channel, or closes the operation. Also when the server side forces channel closure via pvxs::server::ConnectOp::close. The various *Close callbacks may also be used if explicit cleanup is needed on certain conditions.

API

struct pvxs::server::Source

Interface through which a Server discovers Channel names and associates with Handler instances.

User code will sub-class.

Public Functions

void onSearch(Search &op) = 0

Called each time a client polls for the existence of some Channel names (Search::Name).

A Source may only Search::Name::claim() a Channel name if it is prepared to immediately accept an onCreate() call for that Channel name. In other situations it should wait for the client to retry.

void onCreate(std::unique_ptr<ChannelControl> &&op) = 0

A Client is attempting to open a connection to a certain Channel.

This Channel name may not be one which was seen or claimed by onSearch().

Callee may:

  • Do nothing, allowing some other Source with higher/later order a chance to create.

  • Call ChannelControl::close() to explicitly reject the channel.

  • std::move() the op and/or call ChannelControl::setHandler() to accept the new channel.

  • std::move() the op and allow ChannelControl to be destroyed to implicitly reject the channel.

List onList()

A Client is requesting a list of Channel names which we may claim.

void show(std::ostream &strm)

Print status information.

struct List

List of channel names.

Public Members

std::shared_ptr<const std::set<std::string>> names

The list.

bool dynamic

True if the list may change at some future time.

struct Search

An iterable of names (Name) being sought.

virtual void onSearch(Search& search) {
    for(auto& op : search) {
        if(strcmp(op.name(), "magic")==0)
            op.claim();
    }
}

Public Functions

size_t size() const

Number of names.

iterator begin()

Begin iterator of Name instances.

iterator end()

End iterator of Name instances.

const char *source() const

The Client endpoint address.

class Name

A single name being searched.

Public Functions

const char *name() const

The Channel name.

void claim()

The caller claims to be able to respond to an onCreate() for this name.

struct pvxs::server::OpBase

Base for all operation classes.

Subclassed by pvxs::server::ChannelControl, pvxs::server::ConnectOp, pvxs::server::ExecOp, pvxs::server::MonitorControlOp, pvxs::server::MonitorSetupOp

Public Functions

const std::string &peerName() const

The Client endpoint address in “X.X.X.X:Y” format.

const std::string &name() const

The Channel name.

const std::shared_ptr<const ClientCredentials> &credentials() const

Client credentials. Never NULL.

Since

0.2.0

op_t op() const

Operation type.

struct pvxs::server::ExecOp : public pvxs::server::OpBase

Handle when an operation is being executed.

Public Functions

void reply() = 0

Issue a reply without data. (eg. to complete a PUT)

void reply(const Value &val) = 0

Issue a reply with data. For a GET or RPC (or PUT/Get)

void error(const std::string &msg) = 0

Indicate the request has resulted in an error.

void onCancel(std::function<void()>&&) = 0

Callback invoked if the peer cancels the operation before reply() or error() is called.

const Value &pvRequest() const

Access to pvRequest blob

Since

0.2.0

struct pvxs::server::ConnectOp : public pvxs::server::OpBase

Handle when an operation is being setup.

Public Functions

void connect(const Value &prototype) = 0

For GET_FIELD, GET, or PUT. Inform peer of our data-type.

Exceptions
  • std::runtime_error: if the client pvRequest() field mask does not select any fields of prototype.

void error(const std::string &msg) = 0

Indicate that this operation can not be setup.

void onGet(std::function<void(std::unique_ptr<ExecOp>&&)> &&fn) = 0

Handler invoked when a peer executes a request for data on a GET o PUT.

void onPut(std::function<void(std::unique_ptr<ExecOp>&&, Value&&)> &&fn) = 0

Handler invoked when a peer executes a send data on a PUT.

void onClose(std::function<void(const std::string&)>&&) = 0

Callback when the underlying channel closes.

struct pvxs::server::MonitorControlOp : public pvxs::server::OpBase

Handle for active subscription.

Public Functions

bool forcePost(const Value &val)

Add a new entry to the monitor queue. If nFree()<=0 the output queue will be over-filled with this element. Returns

nFree()>0u 
Warning

Caller must not modify the Value

bool post(const Value &val)

Add a new entry to the monitor queue. If nFree()<=0 this element will be “squashed” to the last element in the queue Returns

nFree()>0u 
Warning

Caller must not modify the Value

bool tryPost(const Value &val)

Add a new entry to the monitor queue. If nFree()<=0 return false and take no other action Returns

nFree()>0u 
Warning

Caller must not modify the Value

void finish()

Signal to subscriber that this subscription will not yield any further events. This is not an error. Client should not retry.

void stats(MonitorStat&, bool reset = false) const = 0

Poll information and statistics for this subscription.

Since

1.1.0 Added ‘reset’ argument.

void setWatermarks(size_t low, size_t high) = 0

Set flow control levels.

Flow control operations against an outbound “window” size, which is the number of updates which may be sent before a client ack. must be received. By default both high and low levels are zero.

onLowMark callback is not currently implemented and the ‘low’ level is not used. onHighMark callback will be invoked when a client ack. increases the window size above (>) ‘high’.

void onStart(std::function<void(bool)>&&) = 0

Callback when client resumes/pauses updates.

struct pvxs::server::MonitorSetupOp : public pvxs::server::OpBase

Handle for subscription which is being setup.

Public Functions

std::unique_ptr<MonitorControlOp> connect(const Value &prototype) = 0

Inform peer of our data-type and acquire control of subscription queue. The queue is initially stopped.

Exceptions
  • std::runtime_error: if the client pvRequest() field mask does not select any fields of prototype.

void error(const std::string &msg) = 0

Indicate that this operation can not be setup.

struct pvxs::server::ChannelControl : public pvxs::server::OpBase

Manipulate an active Channel, and any in-progress Operations through it.

Public Functions

void onOp(std::function<void(std::unique_ptr<ConnectOp>&&)>&&) = 0

Invoked when a new GET, PUT, or RPC Operation is requested through this Channel.

void onRPC(std::function<void(std::unique_ptr<ExecOp>&&, Value&&)> &&fn) = 0

Invoked when the peer executes an RPC.

void onSubscribe(std::function<void(std::unique_ptr<MonitorSetupOp>&&)>&&) = 0

Invoked when the peer create a new subscription.

void onClose(std::function<void(const std::string&)>&&) = 0

Callback when the channel closes (eg. peer disconnect)

void close() = 0

Force disconnection If called from outside a handler method, blocks until in-progress Handler methods have returned. Reference to currently attached Handler is released.

struct pvxs::server::MonitorStat

Information about a running monitor.

Public Members

size_t window = 0

Number of available elements in the output flow window.

size_t nQueue = 0

Number of un-sent updates in the local queue. Doesn’t include updates serialized and in the TX buffer.

size_t maxQueue = 0

Highest value of nQueue seen

Since

1.1.0

size_t limitQueue = 0

Negotiated limit on nQueue.

struct pvxs::server::ClientCredentials

Credentials presented by a client.

Primarily a way of presenting peer address and a remote user account name. The method gives the authentication sub-protocol used and is presently one of:

  • “ca” - Client provided account name.

  • ”anonymous” - Client provided no credentials. account will also be “anonymous”.

Since

0.2.0

Public Functions

std::set<std::string> roles() const

Lookup (locally) roles associated with the account.

On *nix targets this is the list of primary and secondary groups in with the account is a member. On Windows targets this returns the list of local groups for the account. On other targets, an empty list is returned.

Public Members

std::string peer

Peer address (eg. numeric IPv4)

std::string iface

The local interface address (eg. numeric IPv4) through which this client is connected. May be a wildcard address (eg. 0.0.0.0) if the receiving socket is so bound.

std::string method

Authentication “method”.

std::string account

Remote user account name. Meaning depends upon method.

Value raw

(Copy of) Credentials blob as presented by the client.