Author: Stefan Eilemann
State: Usable subset implemented in 1.0-alpha
Overview
The administrative API provides access to a running eqServer for the purpose of monitoring and modifying its configuration.
Requirements
- Observe a running configuration, e.g., window viewport changes.
- Allow modification of stopped and running configurations, e.g., adding and removing resources.
- Allow the creation and removal of configurations.
- The admin API is independent of the client interface
- The admin API is not frame-driven
- The admin API does not modify the client's resource tree directly
- The server modifies the client resource tree when it applies a change caused by an admin application
- Modifying a running configuration only requires the modified entities to be initialized or de-initialized.
- Automatic resource discovery (future feature) should use the same mechanism.
Design
The admin API resides in its own namespace. An admin application connects to a
server, which will map a slave instance of the eq::server::Server
and all its children into the admin's process (as
an eq::admin::Server
). The admin application
can sync
this copy whenever it deems it necessary, modify its
copy and commit
the modification. The server will apply the
change and activate when possible, i.e., before the beginning of a new frame
for a running config. A sample update sequence can be
found here. The
modification of data on a mapped object is detailed
in Slave Object Commit.
Namespace Layering
The current implementation (0.9.1) does not use co::Object
data
distribution between the server and the client. It uses custom command packets
to communicate the few allowed modifications.
With the admin interface, there are new two implementations mapping a view of
the server resource hierarchy. Potentially all data will be modifyable. To
accomodate this change, a new eq::fabric
namespace will provide
resource synchronization for
the eq::server
, eq::admin
and eq
implementations. This means that the inheritance for resources is increased
(e.g. eq::Window
→ eq::fabric::Window
→ eq::fabric::Object
→ co::Object
). Furthermore, the data synchronization
between the server, client and admin interfaces will be unified by this
namesapace. The server will retain the master instance of the data.
This requires moving the eq::Object
into
the eq::fabric
namespace, using this class as a base class for all
Equalizer resource entities (Server...Channel) and implementing the proper
serializers. Furthermore, the server has to override the deserialization and
to apply the corresponding tasks upon data modifications.
Slave Object Commit
Committing data on a slave instance was not implemented in Equalizer 0.9.1. Since Equalizer does not know about the application data contained in the serialization streams, there are two options to implement this feature:
- Use a synchronization protocol to ensure no two modifications on the same object happen simultaneously on two instances.
- The application has to either ensure the above or be able to resolve eventual conflicts when synchronizing data.
Using the second approach, the following sequence provides a light-weight implementation for slave object writes:
- The slave instance is mapped and synchronized to a recent version.
- The slave instance modifies some data.
- The slave instance commits the data.
- The data is packed and send to the master instance.
- The master instance receives a notification of the data arrival.
- The master instance applies the received delta datas
using
sync
. This does not create a new version of the object on the master. - (optional) The master instance modifies the object.
- The master instance commits the object.
- All changes since the last commit of the master instance are send to all slave instances.
- The slave instances apply the data.
Note that the slave which modified an object will eventually receive its own modification, and it has to be able to apply this delta. Furthermore, an application using slave writes has either to avoid or to handle the following situations:
- The master commits a new version while the slave modifies it: The slave has to be able to apply the master delta on the modified object, and the master has to be able to apply the slave delta from an older version.
- Multiple slaves modify the same data: The master has to be able to apply multiple, potentially conflicting deltas to its instance.
API
namespace eq { namespace admin { TBD }}
File Format
None
Implementation
- Implement slave object writes
- Implement
eq::fabric
serialization - Use and test 1 and 2 for client and server library
- Specify and implement currently needed subset for admin API
Examples
Run-time Window Creation
namespace eq{ namespace admin{ ServerPtr server = new Server; client->connectServer( server ); // clones full server config ... server->sync(); Pipe* pipe = findPipe( server ); Window* window = new Window( pipe ); window->setIAttribute( ... ); Channel* channel = new Channel( window ); channel->setViewport( ... ); Layout* layout = new Layout( config ); View view = new View( layout ); view->setViewport( ... ); Canvas* canvas = new Canvas( config ); canvas->addLayout( 0 ); canvas->addLayout( layout ); canvas->useLayout( 1 ); Segment* segment = new Segment( canvas ); segment->setViewport( ... ); segment->setWall( ... ); segment->setChannel( channel ); server->commit(); server->sync(); // applies accepted changes }} -> activated on next eq:Config::startFrame, configInit is called on window -> compounds will be created automatically, no scalability
Automatic Resource Discovery
namespace eq { namespace admin { Config* config = new Config; Node* node = new Node( config ); for( each GPU in system ) { Pipe* pipe = new Pipe( node ); pipe->setDevice( i ); } // begin PowerWall nodes for( each display attached ) // parsed from local config file { Window* window = new Window( pipe ); Channel* channel = new Channel( window ); channel->setViewport( ... ); Canvas* canvas = new Canvas( config ); Segment* segment( canvas ); segment->setViewport( ... ); segment->setWall( ... ); segment->setChannel( channel ); } // end PowerWall nodes announce( config ); daemon->waitForTermination(); revoke( config );
Adding nodes to a scalability config
namespace eq { namespace admin { TBD }}
Restrictions
Compounds are not part of the admin API.
Issues
1. How is automatic resource discovery implemented?
Open
The example code above outlines one scenario: A daemon on each node builds a local configuration, which then is announced to the local subnet. Unclear is the exact API for this.
2. How is the applied (vs. commited) change communicated to the requestor?
Open
The server might decide not to apply all changes an admin client has commited, e.g., if a modified entity was removed in the meantime.
3. How are delays handled if a modification requires expensive initialization on a render client, e.g., caused by mapping the scene data required on the node? Who handles this?
Open
The startup has to happen asynchronously to a running config, and the new resources are activately used after they have been initialized.