Class OortObject<T>
- Type Parameters:
T- the type of value object stored in this oort object
- All Implemented Interfaces:
Iterable<OortObject.Info<T>>,EventListener,org.cometd.bayeux.server.ConfigurableServerChannel.Initializer,Oort.CometListener,org.eclipse.jetty.util.component.Dumpable,org.eclipse.jetty.util.component.LifeCycle
- Direct Known Subclasses:
OortContainer
An OortObject represents a named composite entity that is distributed in an Oort cluster.
A typical example is an oort object that stores the number of users connected to an Oort node.
The entity in this case is a long value representing the number of connected users.
Such oort object may be named 'user_count', and there will be an oort object instance with this name in each node.
Each oort object instance will have a different local value, along with all the values from the other nodes.
A particular OortObject has a unique name across the node and is made of N parts,
where N is the number of active nodes. A part is represented by OortObject.Info instances.
Each OortObject.Info instance represents the contribution of that node to the whole OortObject
and stores the Oort URL of the node it represents along with the entity in that node.
+------------+
| user_count |
+---+---+----+---+--------------------+
| part1 | 13 | local - http://oort1/ |
+-------+----+------------------------+
| part2 | 19 | remote - http://oort2/ |
+-------+----+------------------------+
| part3 | 29 | remote - http://oort3/ |
+-------+----+------------------------+
An OortObject must be created and then started:
Oort oort1 = ...; OortObject userCount1 = new OortObject(oort1, "user_count", OortObjectFactories.forLong()); userCount1.start();
Once started, it connects via Oort facilities to the other nodes and communicates with the oort object
instances that have the same name that live in the other nodes.
The communication is performed on a channel constructed from the oort object's name and returned by
getChannelName().
Oort objects work best when the entity they hold is an immutable, value-type object: OortObject<Long>
works better than OortObject<AtomicLong> because AtomicLong is mutable and its APIs
(for example, AtomicLong.compareAndSet(long, long)) are not exposed by OortObject.
Objects stored by an oort object are created using a OortObject.Factory. This is necessary to recreate
objects that may be serialized differently when transmitted via JSON, without forcing a global JSON serializer.
A number of factories are available in OortObjectFactories, and applications can write their own.
Applications can change the entity value of the oort object and broadcast the change to other nodes via
setAndShare(Object, Result). The other nodes will receive a message on the oort object's channel
and set the new entity value in the part that corresponds to the node that changed the entity.
The diagram below shows one oort object with name "user_count" in two nodes.
On the left of the arrow (A), the situation before calling:
userCount1.setAndShare(17, result -> { ... });
and on the right of the arrow (A) the situation afterwards, that shows how the value is first changed
(1) locally on node_1, then a message (2) is broadcast on the cluster, reaches
node_2, where it updates (3) the part corresponding to node_1 to the new value.
+-------------+ +-------------+ +-----------------+ +-----------------+ | node_1 | | node_2 | | node_1 | | node_2 | +-------------+ +-------------+ +-----------------+ (2) +-----------------+ | user_count | | user_count | (A) | user_count | ----> | user_count | +--------+----+ +--------+----+ ----> +--------+--------+ +--------+--------+ | local | 13 | | local | 19 | | local | 17 (1) | | local | 19 | +--------+----+ +--------+----+ +--------+--------+ +--------+--------+ | remote | 19 | | remote | 13 | | remote | 19 | | remote | 17 (3) | +--------+----+ +-------+----+ +--------+--------+ +-------+---------+
When an entity is updated, either locally or remotely, an event is fired to registered OortObject.Listeners.
Oort objects can only update the entity they own; in the example above, node_1 can only update
the "local" value 13 to 17, but cannot modify the "remote" value 19, which is owned by node_2.
Only update messages from node_1 can update the "remote" value on node_2.
Every node has a part that belongs to a particular node, and only that particular node can update it.
Values of oort objects may be merged using a OortObject.Merger via merge(Merger).
A number of mergers are available in OortObjectMergers, and applications can write their own.
For example:
long totalUsersOnAllNodes = userCount1.merge(OortObjectMergers.longSum()); // yields 17+19=36
Oort objects implement a strategy where value objects are replicated in each node, trading increased memory
usage for reduced latency accessing the data.
An alternative strategy that trades reduced memory usage for increased latency is implemented by
OortService.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static classstatic interfaceFactory that creates objects stored byOortObjects.static classThe oort object part holding the object and the metadata associated with it.static interfaceListener for events that update the value of aOortObject.Info, either local or remote.static interfaceA merge strategy for object values.static interfaceAn asynchronous result.Nested classes/interfaces inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener, org.eclipse.jetty.util.component.AbstractLifeCycle.StopExceptionNested classes/interfaces inherited from interface org.cometd.bayeux.server.ConfigurableServerChannel.Initializer
org.cometd.bayeux.server.ConfigurableServerChannel.Initializer.PersistentNested classes/interfaces inherited from interface org.eclipse.jetty.util.component.Dumpable
org.eclipse.jetty.util.component.Dumpable.DumpableContainerNested classes/interfaces inherited from interface org.cometd.oort.Oort.CometListener
Oort.CometListener.Event -
Field Summary
FieldsFields inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
FAILED, STARTED, STARTING, STOPPED, STOPPINGFields inherited from interface org.eclipse.jetty.util.component.Dumpable
KEY -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddListener(OortObject.Listener<T> listener) voidCallback method invoked when a new comet joins the cloudvoidCallback method invoked when a comet leaves the cloudvoidconfigureChannel(org.cometd.bayeux.server.ConfigurableServerChannel channel) Configures the channel used by this oort object.protected Objectdeserialize(Object object) protected voiddoStart()protected voiddoStop()voiddump(Appendable out, String indent) Returns the channel name used by this oort object for communication with other oort objects in other nodes.getInfoByObject(T object) protected Collection<OortObject.Info<T>>getInfos()org.cometd.bayeux.server.LocalSessiongetName()getOort()iterator()<R> Rmerge(OortObject.Merger<T, R> strategy) Merges the objects of all theOortObject.Infos known to this oort object using the givenstrategy.protected OortObject.Info<T>protected voidnotifyRemoved(OortObject.Info<T> info) protected voidnotifyUpdated(OortObject.Info<T> oldInfo, OortObject.Info<T> newInfo) protected voidprotected voidprotected voidvoidremoveListener(OortObject.Listener<T> listener) voidRemoves all listeners.protected ObjectvoidsetAndShare(T newObject, OortObject.Result<T> callback) Sets the given new object on this oort object, and then broadcast the new object to all nodes in the cluster.toString()Methods inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
addEventListener, getEventListeners, getState, getState, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, removeEventListener, setEventListeners, start, stopMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.eclipse.jetty.util.component.Dumpable
dump, dumpSelfMethods inherited from interface java.lang.Iterable
forEach, spliterator
-
Field Details
-
OORT_OBJECTS_CHANNEL
- See Also:
-
-
Constructor Details
-
OortObject
-
-
Method Details
-
doStart
protected void doStart()- Overrides:
doStartin classorg.eclipse.jetty.util.component.AbstractLifeCycle
-
doStop
protected void doStop()- Overrides:
doStopin classorg.eclipse.jetty.util.component.AbstractLifeCycle
-
configureChannel
public void configureChannel(org.cometd.bayeux.server.ConfigurableServerChannel channel) Configures the channel used by this oort object. By default does nothing, but subclasses may override this method to make the channel lazy, for example.- Specified by:
configureChannelin interfaceorg.cometd.bayeux.server.ConfigurableServerChannel.Initializer- Parameters:
channel- the channel to configure- See Also:
-
getOort
- Returns:
- the
Oortinstance associated with this oort object
-
getName
- Returns:
- the name of this oort object, that must be unique across the node.
-
getFactory
- Returns:
- the factory to create objects contained in this oort object
-
getLocalSession
public org.cometd.bayeux.server.LocalSession getLocalSession()- Returns:
- the local session that sends messages to other nodes
-
getChannelName
Returns the channel name used by this oort object for communication with other oort objects in other nodes. The channel is of the form "/oort/objects/<name>" where <name> is this oort object'sname.- Returns:
- the channel name used by this oort object
- See Also:
-
serialize
-
deserialize
-
newInfo
-
cometJoined
Description copied from interface:Oort.CometListenerCallback method invoked when a new comet joins the cloud- Specified by:
cometJoinedin interfaceOort.CometListener- Parameters:
event- the comet event
-
cometLeft
Description copied from interface:Oort.CometListenerCallback method invoked when a comet leaves the cloud- Specified by:
cometLeftin interfaceOort.CometListener- Parameters:
event- the comet event
-
iterator
- Specified by:
iteratorin interfaceIterable<T>- Returns:
- an iterator over the
OortObject.Infoknown to this oort object
-
getInfo
- Parameters:
oortURL- the oort URL used to search the correspondingOortObject.Info- Returns:
- the
OortObject.Infowith the given oort URL, or null if no suchOortObject.Infoexists
-
getInfoByObject
- Parameters:
object- the object used to search the correspondingOortObject.Info- Returns:
- the first
OortObject.Infowhose object equals (via a possibly overriddenObject.equals(Object)) the givenobject
-
merge
Merges the objects of all theOortObject.Infos known to this oort object using the givenstrategy.- Type Parameters:
R- the merge result type- Parameters:
strategy- the strategy to merge the objects- Returns:
- the merged result
-
addListener
- Parameters:
listener- the listener to add- See Also:
-
removeListener
- Parameters:
listener- the listener to remove- See Also:
-
removeListeners
public void removeListeners()Removes all listeners. -
notifyUpdated
-
notifyRemoved
-
onObject
-
pushInfo
-
pullInfo
-
getInfos
-
dump
- Specified by:
dumpin interfaceorg.eclipse.jetty.util.component.Dumpable- Throws:
IOException
-
toString
- Overrides:
toStringin classorg.eclipse.jetty.util.component.AbstractLifeCycle
-