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 Source

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

User code will sub-class.

Public Functions

virtual 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.

virtual 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.

virtual List onList()

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

virtual 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

inline size_t size() const

Number of names.

inline iterator begin()

Begin iterator of Name instances.

inline iterator end()

End iterator of Name instances.

inline const char *source() const

The Client endpoint address.

class Name

A single name being searched.

Public Functions

inline const char *name() const

The Channel name.

inline void claim()

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

struct 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

inline const std::string &peerName() const

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

inline const std::string &name() const

The Channel name.

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

Client credentials. Never NULL.

Since

0.2.0

inline op_t op() const

Operation type.

struct ExecOp : public pvxs::server::OpBase

Handle when an operation is being executed.

Public Functions

virtual void reply() = 0

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

virtual void reply(const Value &val) = 0

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

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

Indicate the request has resulted in an error.

Since

1.2.3 Does not block

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

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

inline const Value &pvRequest() const

Access to pvRequest blob

Since

0.2.0

struct ConnectOp : public pvxs::server::OpBase

Handle when an operation is being setup.

Public Functions

virtual void connect(const Value &prototype) = 0

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

Throws:

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

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

Indicate that this operation can not be setup

Since

1.2.3 Does not block

virtual 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.

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

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

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

Callback when the underlying channel closes.

struct MonitorControlOp : public pvxs::server::OpBase

Handle for active subscription.

Public Functions

inline 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

inline 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

inline 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

inline void finish()

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

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

Poll information and statistics for this subscription.

Since

1.1.0 Added ‘reset’ argument.

virtual 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. is received and the window size is above (>) ‘high’.

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

Callback when client resumes/pauses updates.

struct MonitorSetupOp : public pvxs::server::OpBase

Handle for subscription which is being setup.

Public Functions

virtual 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.

Throws:

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

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

Indicate that this operation can not be setup

Since

1.2.3 Does not block

struct ChannelControl : public pvxs::server::OpBase

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

Public Functions

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

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

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

Invoked when the peer executes an RPC.

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

Invoked when the peer create a new subscription.

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

Callback when the channel closes (eg. peer disconnect)

virtual 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 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.

size_t nSquash = 0

Number of updates squashed during post() calls

Since

1.2.0

struct 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.