#define S_DOCUMENTATION #define S_DOCUMENTATION_DEVELOPER #define PAGE Documentation #define SUBPAGE Developer #define TITLE Distributed Objects #include "header.shtml"
Author: eilemann@gmail.com
State:
Equalizer provides facilities to ease the data distribution of an
application. The central piece is the eq::net::Object base class,
from which distributed objects are derived. Objects become accessable by
making them known to a session. The example code shipped with Equalizer
contains examples of distributed objects.
Equalizer can manage static and versioned objects.
Static objects can be instanciated on multiple nodes. Upon instanciation, the data from the master version is replicated to the 'slave' node. Static objects do not retain object data, since this data is assumed to be immutable.
Versioned objects work like a simplified version control system. One
master copy of the object creates a new version whenever the application
calls Object::commit. This version is pushed to all subscribers,
that is, to all nodes which have mapped the object. The version data is queued
on the object, and will be applied when the application
calls Object::sync to synchronize a specific version, or the head
version.
A simplified type of versioned objects are objects where the instance data is equal to the delta data, i.e., objects which sync their full data on each commit.
To make objects distributable, they have to be known by the session. During this process the change type of object is determined.
The master instance of an object is registered
using Session::registerObject. Upon registration, a
session-unique identifier is assigned, which can be used to map slave
instances using Session::mapObject. Mapped slave instance are
instanciated with the oldest known version from the master instance, and can
be synchronized to the head version using Object::sync.
Additionally, the object identifier can be used to send
an ObjectPacket to another node. Each object instance has a
node-unique instance identifier to address single instances of an object on a
remote node.
During the registration of the master version of a distributed object, the way
changes are to be handled is determined by
calling Object::getChangeType. The change type determines the
memory footprint and the contract for calling the serialization methods. The
following change types are possible:
The implementation of unversioned objects is straight-forward and requires the
application to either declare the distributed data using
Object::setInstanceData or to implement
Object::getInstanceData.
Versioned objects override the method Object::getChangeType to
indicate how changes are to be handled. They possibly have to implement, in
addition to unversioned objects, the methods Object::pack
and Object::unpack to create or apply a diff from the last
version. Alternatively they can declare the location of the data
using Object::setDeltaData on both the master and slave
instances.
Objects with the same instance and delta data only distribute instance data for each new version, and do not have to implement pack and unpack.
The object serialization and deserialization methods use
an DataOStream and DataIStream, respectively. These
streams behave like iostreams, but transfer the data in a binary format. They
do no type-checking on the data, that is, it is the application's
responsibility to match the order and variables during serialization
and deserialization exactly. Currently they implement streaming
operators for basic data types (int, float, etc.), std::strings and
std::vectors of basic data types.
Design only:
Provide type with objects:
virtual uint32_t Object::getTypeID() const { return EQ_ID_INVALID; }
Session::instantiateObject( const uint32_t objectID ):
if( !get object type id from master )
return 0
Session::createObject( type );
map object to objectID
return object
Design only!
- each thread has its own version.
- only one write thread per object across all nodes
- sync and getVersion are thread-specific, that is, sync synchronizes this
object to the given version for this thread only, and getVersion return the
current version for this thread.
class ???
{
ObjectHandle getObject( const uint32_t id, const uint32_t version );
};
// ObjectHandle releases object/version for reuse when it goes out of scope
The header file is in src/lib/net/object.h.
Each object has a change manager, which depends on the type of the object and its master/slave status. Equalizer implements a change manager for static objects, versioned objects with delta data and versioned objects with only instance data. Externalizing the implementation of change handling allows for optimisations in the implementation and the memory usage for storing the version data.
Document Session::attachObject for unmanaged
objects. Document object version obsoletion.