Turi Create  4.0
cppipc::comm_server Class Reference

#include <core/system/cppipc/server/comm_server.hpp>

Public Member Functions

 comm_server (std::vector< std::string > zkhosts, std::string name, std::string alternate_bind_address="", std::string alternate_control_address="", std::string alternate_publish_address="", std::string secret_key="")
 
 ~comm_server ()
 Destructor. Stops receiving messages, and closes all communication.
 
void start ()
 
void stop ()
 
std::string get_bound_address ()
 
std::string get_control_address ()
 
std::string get_status_address ()
 
void * get_zmq_context ()
 
void report_status (std::string status_type, std::string message)
 
void delete_object (size_t objectid)
 
template<typename T >
void register_type (std::function< T *()> constructor_call)
 
template<typename T >
void register_type (std::function< std::shared_ptr< T >()> constructor_call)
 
template<typename T >
size_t register_object (std::shared_ptr< T > object)
 
size_t find_object (void *object)
 
std::shared_ptr< void > get_object (size_t objectid)
 
template<typename MemFn >
void register_function (MemFn fn, std::string function_name)
 

Detailed Description

The comm_server manages the server side of the communication interface.

The comm_server manages the serving of objects. It listens on a bind address (defaults to an arbitrary TCP port, but an alternate_bind_address can be provided), and registers its existance in zookeeper. Clients can reach the server by associating with the same keys in zookeeper.

The comm_server manages a list of member function pointers and strings they map to, as well as a complete list of all served objects.

Basic Utilization

To create a object which can be served by remote machines, first create a base interface class which describes the functions to be exported using the registration macros REGISTRATION_BEGIN REGISTRATION_END REGISTER, or the magic macros GENERATE_INTERFACE and GENERATE_INTERFACE_AND_PROXY. The actual server side implementation of the object then inherits from this interface, implementing all the functions.

For instance, I may have a base interface class called "file_write_base", and an implementation called "file_write_impl".

class file_write_base {
public:
virtual int open(std::string s) = 0;
virtual void write(std::string s) = 0;
virtual void close() = 0;
virtual ~file_write_base() {}
REGISTRATION_BEGIN(file_write_base)
REGISTER(file_write_base::open)
REGISTER(file_write_base::write)
REGISTER(file_write_base::close)
REGISTRATION_END
};
class file_write_impl: public file_write_base {
file_write_impl(); // regular constructor
explicit file_write_impl(std::string f) { // open a file on construction
open(f);
}
// ... other implementation details omitted ...
};

To make this class available on the server side, we must tell the server how to construct an instance of this object by registering a type with the server, and providing a lambda function returning a pointer to an implementation.

int main() {
...
comm_server server(...);
server.register_type<file_write_base>([](){ return new file_write_impl;});
...
server.start();
...
}

Here we use the trivial constructor, but more generally we can provide arbitrarily interesting constructors in the lambda. For instance, here we use the alternate constructor in file_write_impl.

int main() {
...
comm_server server(...);
server.register_type<file_write_base>([](){ return new file_write_impl("log.txt");});
...
server.start();
...
}

Once the server is started, the client will have the ability to create proxy objects which in turn create matching objects on the server.

It is important that each base class only describes exactly one implementation. i.e. register_type<T> should be used only once for any T.

To see how this code is used, see the comm_client documentation.

Implementation Details

There is a special "root object" which manages all "special" tasks that operate on the comm_server itself. This root object always has object ID 0 and is the object_factory_base. This is implemented on the server side by object_factory_impl, and on the client side as object_factory_proxy.

The object_factory_impl manages the construction of new object types.

Interface Modification Safety

The internal protocol is designed to be robust against changes in interfaces. i.e. if new functions are added, and the server is recompiled, all previous client builds will still work. Similarly, if new functions are added and the client is recompiled, the new client will still work with old servers as long as the new functions are not called.

Definition at line 144 of file comm_server.hpp.

Constructor & Destructor Documentation

◆ comm_server()

cppipc::comm_server::comm_server ( std::vector< std::string >  zkhosts,
std::string  name,
std::string  alternate_bind_address = "",
std::string  alternate_control_address = "",
std::string  alternate_publish_address = "",
std::string  secret_key = "" 
)

Constructs a comm server which uses remote communication via zookeeper/zeromq.

Parameters
zkhostsThe zookeeper hosts to connect to. May be empty. If empty, the "alternate_bind_address" parameter must be a zeromq endpoint address to bind to.
nameThe key name to wait for connections on. All remotes connect to this server on this name. If zkhosts is empty, this is ignored.
alternate_bind_addressThe communication defaults to using an arbitrary TCP port. This can be changed to any URI format supported by zeroMQ.
alternate_publish_addressOnly valid if zkhosts is empty. The address to publish server statuses on. If zookeeper is not used, all remotes should connect to this address to get server status. If not provided, one is generated automatically.

Member Function Documentation

◆ delete_object()

void cppipc::comm_server::delete_object ( size_t  objectid)
inline

Deletes an object of object ID objectid.

Definition at line 293 of file comm_server.hpp.

◆ find_object()

size_t cppipc::comm_server::find_object ( void *  object)
inline

Returns an object ID of the object has been previously registere.d Returns (size_t)(-1) otherwise.

Definition at line 362 of file comm_server.hpp.

◆ get_bound_address()

std::string cppipc::comm_server::get_bound_address ( )

Gets the address we are bound on

◆ get_control_address()

std::string cppipc::comm_server::get_control_address ( )

Gets the address where we receive control messages

◆ get_object()

std::shared_ptr<void> cppipc::comm_server::get_object ( size_t  objectid)
inline

Returns a pointer to the object with a given object ID. Returns NULL on failure.

Definition at line 375 of file comm_server.hpp.

◆ get_status_address()

std::string cppipc::comm_server::get_status_address ( )

Gets the address on which you can subscribe to for status updates.

◆ get_zmq_context()

void* cppipc::comm_server::get_zmq_context ( )

Gets the zeromq context.. Deprecated. Returns NULL.

◆ register_function()

template<typename MemFn >
void cppipc::comm_server::register_function ( MemFn  fn,
std::string  function_name 
)

Registers a member function pointer. Do not use directly. Used by the REGISTER macros to allow the comm_server to maintain the mapping of member function pointers to names.

Definition at line 408 of file comm_server.hpp.

◆ register_object()

template<typename T >
size_t cppipc::comm_server::register_object ( std::shared_ptr< T >  object)
inline

Registers an object to be managed by the comm server, returning the new object ID. If the object already exists, the existing ID is returned.

Definition at line 346 of file comm_server.hpp.

◆ register_type() [1/2]

template<typename T >
void cppipc::comm_server::register_type ( std::function< T *()>  constructor_call)
inline

Registers a type to be managed by the comm_server. After registration of this type, remote machines will be able to create instances of this object via the comm_client's make_object function call.

Definition at line 314 of file comm_server.hpp.

◆ register_type() [2/2]

template<typename T >
void cppipc::comm_server::register_type ( std::function< std::shared_ptr< T >()>  constructor_call)
inline

Registers a type to be managed by the comm_server. After registration of this type, remote machines will be able to create instances of this object via the comm_client's make_object function call.

Definition at line 330 of file comm_server.hpp.

◆ report_status()

void cppipc::comm_server::report_status ( std::string  status_type,
std::string  message 
)

Publishes a message of the form "[status_type]: [message]". Since the client can filter messages, it is important to have a small set of possible status_type strings. For the purposes of the comm_server, we define the following:

  • COMM_SERVER_INFO Used for Comm Server informational messages.
  • COMM_SERVER_ERROR Used for Comm Server error messages.

These status strings are defined in core/system/cppipc/common/status_types.hpp

◆ start()

void cppipc::comm_server::start ( )

Start receiving messages. Message processing occurs on a seperate thread, so this function returns immediately..

◆ stop()

void cppipc::comm_server::stop ( )

Stops receiving messages. Has no effect if start() was not called before this.


The documentation for this class was generated from the following file: