ReactiveMachine is a java-written reactive framework. It implements agents, which interact in a deterministic way, by using the reactive paradigm. This framework invites to experiment with something like collaborative programming. With its version 2.0 ReactiveMachine has been made more consistent and understandable. It seem suited to the implementation of simulators. Any return of your experience on this product would be appreciated.
The purpose of this document is to describe origins, design and use of the ReactiveMachine software. In order to get a good understanding of it, you should be familiar with object-oriented programming and Java.
Software version | 2.0 |
Documentation version | 2.0 |
ReactiveMachine has mainly been inspired by reading publications around the Inria Mimosa project on reactive programming and more particularly on the Fair Threads framework. Like Fair Threads, ReactiveMachine installs a synchronization system between threads: the ReactiveMachine community corresponds to the Fair Threads scheduler. Unlike Fair Threads, ReactiveMachine is not deterministic about thread execution order.
At the centre of the ReactiveMachine is the ReactiveCommunity. A ReactiveCommunity accepts the connection of ReactiveEntities. Together, a ReactiveCommunity and its connected ReactiveEntities assume the reactive paradigm.
Each ReactiveEntity is associated to a Java thread, which gives life to an Agent. Application programming takes place through agents. An Agent is a java object overriding AgentImpl, which applies the reactive paradigm by using the primitives offered by its associated reactive entity. An Agent also has access to some primitives offered by the reactive community to which it is connected.
Life time of an Agent is composed of three phases: initialization, participation and termination. During initialization the Agent receives context information, during participation it expresses its own behavior an during termination it closes what is necessary.
At a given time, an Agent is (through its entity) either connected or not connected to a community. It cannot be connected to more than one community. For connecting or disconnecting itself, an Agent uses respectively the connect() or disconnect() method of its entity.
From version 2.0 of the ReactiveMachine, a ReactiveCommunity is no more associated to a thread. It becomes a simple synchronization object.
Concept | Contract | Implementation |
---|---|---|
ReactiveCommunity | org.xmloperator.reactive. ReactiveCommunity | org.xmloperator.reactive.impl. ReactiveCommunityImpl |
ReactiveEntity | org.xmloperator.reactive. ReactiveEntity | org.xmloperator.reactive.impl. ReactiveEntityImpl |
Agent | org.xmloperator.reactive. Agent | org.xmloperator.reactive.agent. AgentImpl |
A community defines instants. An instant is identified by a long value. The activity of the connected entities occurs during instants. One instant can end only when all connected entities have agreed to that. The community makes the observation of the end of an instant and begins a new one (by incrementing its long value).
Since an instant is lived fully or not, entity connections and disconnections always occur during the end-of-instant, which is a dead time between successive instants.
An Agent declares to stop its activity for the current instant without condition by calling the stop() method of its entity. The call return will occur at the beginning of the next instant.
An Agent declares to suspend its activity for the current instant by calling the suspend() method of its entity. If all the other connected agents do the same then the call returns null at the beginning of the next instant. In contrast, if an elementary Event (see next section) is broadcasted during this instant then the method returns this broadcasted event during the same instant.
Thus the agents connected to a community have two ways to synchronize:
An instant can contain any number of suspensions.
Events support reactive communication between agents connected to a community. An Event is created by a community (at the request of an Agent) and belongs to this community. Any connected Agent can generate any event of its community.
There is two types of Event:
The type of an Event is decided in its creation.
An Event is or is not generated during a given instant. This is the reason why an elementary Event can be immediately broadcasted. Another Agent (or the same) is allowed to generate the same elementary Event during the same instant but with no effect.
A Message Event cannot be broadcasted during the instant of generation because another Agent can generate the same Message Event with another Message, which will be lost since event broadcasting already occurs during the instant. Broadcasting of a Message Event is differed to the beginning of the next instant. The Message Event is broadcasted with all the generated Messages.
A Message is sender certified: a recipient Agent can take note of the entity identifier of the sender.
Concept | Contract | Implementation |
---|---|---|
Event | org.xmloperator.reactive. Event | org.xmloperator.reactive.impl. EventImpl |
MessageEvent | org.xmloperator.reactive. MessageEvent | org.xmloperator.reactive.impl. MessageEventImpl |
Message | org.xmloperator.reactive. Message | org.xmloperator.reactive.impl. MessageImpl |
Warning: the term "Message" has changed meaning in version 2.0. In version 1.0, it pointed to the Message Event.
The object that is responsible of creating communities and launching agents is the ReactiveMachine. The ReactiveMachine is unique within the Java virtual machine. A reference to a ReactiveMachine is obtained through a ReactiveFactory.
At launching, an Agent receives a LaunchingContext. it contains reference to:
Concept | Contract | Implementation |
---|---|---|
ReactiveMachine | org.xmloperator.reactive. ReactiveMachine | org.xmloperator.reactive.impl. ReactiveMachineImpl |
ReactiveFactory | org.xmloperator.reactive. ReactiveFactory | org.xmloperator.reactive.impl. ReactiveFactoryImpl |
LaunchingContext | org.xmloperator.reactive. LaunchingContext | org.xmloperator.reactive.impl. LaunchingContextImpl |
Often multiple agents may need to store the same information. It is thus tempting to share this information but it must be done without affecting the determinism. This is realized by the community Board, whose data can change only during end-of-instants.
For making the board (or any other environment of the community) data change during end-of-instants, actions are used. An Action is generated by an Agent using an ActionMessage. The Action is executed during the end-of-instant, while the ActionMessage is broadcasted at the beginning of the next instant as every Message.
Reversing an Action is not proposed because usually not deterministic.
Concept | Contract | Implementation |
---|---|---|
Board | org.xmloperator.reactive.Board | org.xmloperator.reactive.impl. BoardImpl |
ActionMessage | org.xmloperator.reactive. ActionMessage | org.xmloperator.reactive.impl. ActionMessageImpl |
Action | org.xmloperator.reactive. Action | org.xmloperator.reactive.impl. ActionImpl |
A trace system is avalaible for debugging. It is activated by calling the setTrace() method of ReactiveFactoryImpl. Trace activation operates at the class level: if traces are on for a class then all the instances of this class will generate traces.
The classes that propose traces are the following:
Following are examples of traces:
Trace | Comments |
---|---|
A2 is [..]SyracuseAgent/13 | Agent number 2 is launched. |
C1.2 A3 suspend | Within Community 1, during instant 2, Agent 3 suspends. |
C1.2 A3 generates E4 | Within Community 1, during instant 2, Agent 3 generates Event 4. |
C1.2 A3 generates ME5 A3("Hello") | Within Community 1, during instant 2, Agent 3 generates the MessageEvent 5 with the Message "Hello". |
ReactiveMachine is done | All agents are done. |
Particular attention was paid to make the ReactiveMachine simpler and more focused on its function. All that appeared unnecessary or overly complex was eliminated.
About ReactiveCommunity :
About events and messages :
About actions :
About agents :
Your application program should include the following java packages :
This board implementation is as simple as possible. Its role is to invite all the agents to either continue or terminate. The Agent that wants to invite the others to terminate has to generate an ActionMessage with an ExitAction. The execution of ExitAction during the end-of-instant has the effect of calling the terminate() method of the ExitBoard.
Concept | Implementation |
---|---|
ExitAction | org.xmloperator.reactive.demo.syracuse. ExitAction |
ExitBoard | org.xmloperator.reactive.demo.syracuse. ExitBoard |
This board implementation is pretty generic (but complex). This is a hierarchical structure of elements that looks very like the Document Object Model (DOM) of the W3C. An advantage of such a data structure is that it can be easily read or written as an XML content.
An Element is either a ParentElement, a DataElement or an empty element. A ParentElement can have children elements, a DataElement cannot, neither an empty one. Any Element has a local name and, possibly, a namespace URI.
A DataElement is a recipient for a data with a given data type, which corresponds to a Java type. Used data types are: long, double, string and object. An object data type corresponds to a TranslatableObject. A TranslatableObject is an Object with a method for translating it to an Element and another method that is used for instantiating an Object, called Rebuilder, which is able to rebuild the TranslatableObject from its representing Element.
Conformant to the board contract, all element attributes are readable (by any agent) but none are (directly) writable. TranslatableObjects have to conform to the same contract.
Concept | Contract | Implementation |
---|---|---|
Element | org.xmloperator.reactive.element. Element | org.xmloperator.reactive.element.impl. ElementImpl |
ParentElement | org.xmloperator.reactive.element. ParentElement | org.xmloperator.reactive.element.impl. ParentElementImpl |
DataElement | org.xmloperator.reactive.element. DataElement | org.xmloperator.reactive.element.impl. [Long|Double|String|Object]DataElementImpl |
TranslatableObject | org.xmloperator.reactive.element. TranslatableObject | |
Rebuilder | org.xmloperator.reactive.element. Rebuilder |
In order to modify an Element (during an end-of-instant) the board uses a RWElement. The access to this RWElement requires a key that only the board has.
Concept | Contract | Implementation |
---|---|---|
RWElement | org.xmloperator.reactive.element.RWElement | org.xmloperator.reactive.element.impl. RWElementImpl |
The following Actions on Element are available:
Action | Description | Implementation |
---|---|---|
Insert | A given element is inserted before a reference Element. | org.xmloperator.reactive.element.action. ElementInsertAction |
Append | A given Element is appended as last child of a reference ParentElement. | org.xmloperator.reactive.element.action. ElementAppendAction |
Remove | A reference Element is removed. | org.xmloperator.reactive.element.action. ElementRemoveAction |
ChildrenRemove | The children of a reference ParentElement are removed. | org.xmloperator.reactive.element.action. ChildrenRemoveAction |
ChildrenSort | The children of a reference ParentElement are sorted using a Comparator of Element. | org.xmloperator.reactive.element.action. ChildrenSortAction |
Constraints can be set on the children elements of a ParentElement. The following ChildrenConstraints are available:
Constraint | Description | Implementation |
---|---|---|
DifferentNames | Two children elements of a ParentElement cannot have the same name (local name and namespace URI). | org.xmloperator.reactive.element.constraint. DifferentNamesChildrenConstraint |
FixedName | All the children elements of a ParentElement have the same given name (local name and namespace URI). | org.xmloperator.reactive.element.constraint. FixedNameChildrenConstraint |
ChildCount | The count of the children elements of a ParentElement cannot be less than a min value after a remove operation neither greater than a max value (-1 for no max value) after an insert/append operation. | org.xmloperator.reactive.element.constraint. ChildCountChildrenConstraint |
An ElementAction whose execution is contrary to a ChildrenConstraint returns a ChildrenConstraintException in the ActionMessage.
Concept | Contract |
---|---|
ChildrenConstraint | org.xmloperator.reactive.element.ChildrenConstraint |
The ElementBoard provides access to the RootElement, which is a ParentElement. Namespaces are handeld at RootElement level.
Concept | Contract | Implementation |
---|---|---|
ElementBoard | org.xmloperator.reactive.element. ElementBoard | org.xmloperator.reactive.element.impl. ElementBoardImpl |
RootElement | org.xmloperator.reactive.element. RootElement | org.xmloperator.reactive.element.impl. RootElementImpl |
Saving and restoring a RootElement are respectively assumed by the DocumentWriter and DocumentReader objects.
Object | Implementation |
---|---|
DocumentWriter | org.xmloperator.reactive.element.util. DocumentWriter |
DocumentReader | org.xmloperator.reactive.element.util. DocumentReader |
The DOM-like Element Board uses the following java packages :
This section focuses on the programs that have been developed for the demonstration of the ReactiveMachine.
It's actually a single Java program Test.main() that performs a series of tests. Each test is realized by a procedure, which executes the following instructions:
A ReactiveMachine is instancied using the ReactiveFactoryImpl.REACTIVE_FACTORY.
A first Agent is launched. It may launch others.
A ReactiveMachine.done() call can be made when the first Agent has completed his launch. This done order will remain pending as long as an Agent alive.
Each Agent, at one point, decides to terminate.
The ReactiveMachine detects that there is no one living Agent and terminates. The test procedure is terminated. A new one can begin.
A CrashingReport object stores data about Agent crashing. At the end, if no crash is detected, the following message is printed on System.out:
No agent crashes
The various tests are described in the following sections.
Concept | Contract | Implementation |
---|---|---|
Test | org.xmloperator.reactive.demo. Test | |
CrashingReport | org.xmloperator.reactive. CrashingReport | org.xmloperator.reactive.demo. CrashingReportImpl |
This is a very basic test.
One Agent is launched. It executes one stop and two suspend. The effect is the same: going to the next instant.
This a stress test for launching agents.
The SyracuseAgent recursively launches new instances of itself. Once a target is reached an ExitAction is generated, destined to the ExitBoard.
Concept | Implementation |
---|---|
SyracuseAgent | org.xmloperator.reactive.demo.syracuse. SyracuseAgent |
This test concerns elementary events.
An EventListenerAgent creates and launches a number of EventGeneratorAgent, each one associated with an elementary Event. Each generator Agent generates its own Event at each instant. The listener Agent notes at each instant the order of received events. Arrived at a given instant, the different sequences and their frequencies are displayed. The result differs from one Java virtual machine to another.
Concept | Implementation |
---|---|
EventListenerAgent | org.xmloperator.reactive.demo.event. EventListenerAgent |
EventGeneratorAgent | org.xmloperator.reactive.demo.event. EventGeneratorAgent |
This is another test about elementary events.
Four players meet for a card game. At the beginning, each player has eight cards in hand. They are marked 0-7 (the zero card is the highest) and are shuffled. Each turn each player reveals his first card. The highest card wins all the other. In case of equality (battle) the involved players reveal a new card. A player loses when he has no cards. The last wins.
Each card of each player is represented by an elementary Event. The role of a player is held by a BattlePlayerAgent.
Concept | Implementation |
---|---|
BattlePlayerAgent | org.xmloperator.reactive.demo.battle. BattlePlayerAgent |
This test is about Message events.
Three players are in a circle. A player who receives a ball from the left returns it to the right and vice versa. The game begins when a player throws a ball to his right and one on his left.
A player is represented by a BallPlayerAgent. Passing a ball to another player is generating a Message that contains the entity identifier of the destination Agent.
Concept | Implementation |
---|---|
BallPlayerAgent | org.xmloperator.reactive.demo.ball. BallPlayerAgent |
This test is similar to a real simulation. It evokes a trading room where shared values are called resources.
There are two main types of actor:
A transaction uses three instants:
Concept | Implementation |
---|---|
Operator | org.xmloperator.reactive.demo.market.agent. Operator |
Transformer | org.xmloperator.reactive.demo.market.agent. Transformer |
The ReactiveMachine software is provided in source form exclusively. Its execution display needs a Java development platform, such as Eclipse.
In order to install the software with Eclipse you have to:
The ReactiveMachine software uses a JavaSE-1.6 JRE System Library.
Running the software (Run / Run) needs to specify its main class: org.xmloperator.reactive.demo.Test
Last update: 2011-09-29 | Copyright (c) 2008, 2011 The_xmloperator_project |