This tutorial is intended to give a general, but brief overview about the concept of the DWARF concept.
Feel free to extend it, when you think important imformation is missing.
Services
An application in the DWARF framework consists of different services. Each
service is a process running on the same or on different machines.
A service has a dedicated task to fulfill. I.e. a collision detection service receives location information of various tracking sources (or other sources providing location information) and computes, if two or more objects have intersections. If so, the collision detection service might provide information about these collisions.
Needs & Abilities
As we have seen, services might provide information, but even may require information to work properly.
In DWARF both aspects are modelled as
needs and
abilities. If one service offers information as an ability, another one can get access to this information by revealing a corresponding need.
Both, needs and abilities are identifiable by their
type and a
connector protocol. The type and the protocol must match on both sides. The types must be equal, but the protocols differ, following these rules: If a service wants to send information as events, it has to use the
PushSupplier protocol and if a service is going to receive events it has to reveal the
PushConsumer protocol. A second way of communication can be realized by direct method calls. For this, the service whose methods are going to be called has to offer a ability for
ObjrefExporter and the one which will call the moethods has to have a need of the
ObjrefImporter protocol. The third and currently last way of communication between two services is offered by shared memory (Note that this kind of communication only works for services running on the same machine.). Here, both services use the same protocol
Shmem.
The two services in the following example will get interconnected by an event channel:
<service name="CollisionDetectionService">
<ability name="giveCollisions" type="CollisionData">
<connector protocol="PushSupplier"/>
</ability>
</service>
<service name="CollisionReceiver">
<need name="giveCollisions" type="CollisionData">
<connector protocol="PushConsumer"/>
</need>
</service>
In general, service's connectivities are described in so called
Service Descriptions. These are specified in XML-files and are structured by a Document Type Definition (DTD).
See
DwarfMiddlewareTutorialLesson4 for further details.
The ServiceManager and Communication Channels
The
ServiceManager is a process that manages all participating services. It has to run on every machine that has services which shall participate in an application. (
OkOk?, a service can also be started on a machine without a
ServiceManager running, but in this case, the service has to connect to a
ServiceManger? on another computer.)
What happens on startup of the
ServiceManager is the following:
After startup, the
ServiceManager reads all XML-Service Descriptions from one of its install directories and creates similar named datatypes in memory for each parsed description. The
ServiceManager detects all other
ServiceManagers in the same network by SLP (Service Location Protocol) and compares all needs to all abilities. If two match, a communication channel is opened and given to the need on the one hand and to the ability on the other.
Self describing services are services that are started as a seperate process, connect to the
ServiceManager and describe themselves by creating the
ServiceDescription datatypes without an existing XML-file.
Attributes & Predicates
Service Descriptions and also be used to configure a service. Therefore
attributes have been introduced to Service Descriptions. An attribute has a
name and a
value.
For example, the following example would start the collision detection service with two attributes, one indicating the room and the other a frequency. If the service is started, the service description is given to the service and by this, the service can analyse the description. In our example, the service could configure itself just to send collisions events occuring in the room called lab and sending these events with a frequency of 10 events per second.
<service name="CollisionDetectionService">
<attribute name="room" value="lab">
<ability name="giveCollisions" type="CollisionData">
<attribute name="frequency" value="10">
<connector protocol="PushSupplier"/>
</ability>
</service>
The use of
predicates allows developers to restrict the selection of services. I.e. the following service will only get connected to services which accomply its predicates, mean the previous one:
<service name="CollisionReceiver">
<need name="giveCollisions" type="CollisionData" predicate="&((room=lab)(frequency>7))">
<connector protocol="PushConsumer"/>
</need>
</service>
--
MarcusToennis - 09 Jul 2004