T
- the type of value object stored in this oort objectjava.lang.Iterable<OortObject.Info<T>>
, java.util.EventListener
, org.cometd.bayeux.server.ConfigurableServerChannel.Initializer
, Oort.CometListener
OortContainer
public class OortObject<T> extends org.eclipse.jetty.util.component.AbstractLifeCycle implements org.cometd.bayeux.server.ConfigurableServerChannel.Initializer, Oort.CometListener, java.lang.Iterable<OortObject.Info<T>>
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);
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.Listener
s.
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
.
Modifier and Type | Class | Description |
---|---|---|
protected static class |
OortObject.Data<T> |
|
static interface |
OortObject.Factory<T> |
Factory that creates objects stored by
OortObject s. |
static class |
OortObject.Info<T> |
The oort object part holding the object and the metadata associated with it.
|
static interface |
OortObject.Listener<T> |
Listener for events that update the value of a
OortObject.Info , either local or remote. |
static interface |
OortObject.Merger<T,R> |
A merge strategy for object values.
|
static interface |
OortObject.Result<R> |
An asynchronous result.
|
org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener
org.cometd.bayeux.server.ConfigurableServerChannel.Initializer.Persistent
Oort.CometListener.Adapter, Oort.CometListener.Event
Modifier and Type | Field | Description |
---|---|---|
protected org.slf4j.Logger |
logger |
|
static java.lang.String |
OORT_OBJECTS_CHANNEL |
Constructor | Description |
---|---|
OortObject(Oort oort,
java.lang.String name,
OortObject.Factory<T> factory) |
Modifier and Type | Method | Description |
---|---|---|
void |
addListener(OortObject.Listener<T> listener) |
|
void |
cometJoined(Oort.CometListener.Event event) |
Callback method invoked when a new comet joins the cloud
|
void |
cometLeft(Oort.CometListener.Event event) |
Callback method invoked when a comet leaves the cloud
|
void |
configureChannel(org.cometd.bayeux.server.ConfigurableServerChannel channel) |
Configures the channel used by this oort object.
|
protected java.lang.Object |
deserialize(java.lang.Object object) |
|
protected void |
doStart() |
|
protected void |
doStop() |
|
java.lang.String |
getChannelName() |
Returns the channel name used by this oort object for communication with other oort objects in other nodes.
|
OortObject.Factory<T> |
getFactory() |
|
OortObject.Info<T> |
getInfo(java.lang.String oortURL) |
|
OortObject.Info<T> |
getInfoByObject(T object) |
|
protected java.util.Collection<OortObject.Info<T>> |
getInfos() |
|
org.cometd.bayeux.server.LocalSession |
getLocalSession() |
|
java.lang.String |
getName() |
|
Oort |
getOort() |
|
java.util.Iterator<OortObject.Info<T>> |
iterator() |
|
<R> R |
merge(OortObject.Merger<T,R> strategy) |
Merges the objects of all the
OortObject.Info s known to this oort object using the given strategy . |
protected OortObject.Info<T> |
newInfo(T local) |
|
protected void |
notifyRemoved(OortObject.Info<T> info) |
|
protected void |
notifyUpdated(OortObject.Info<T> oldInfo,
OortObject.Info<T> newInfo) |
|
protected void |
onObject(java.util.Map<java.lang.String,java.lang.Object> data) |
|
protected void |
pullInfo(java.lang.String oortURL) |
|
protected void |
pushInfo(java.lang.String oortURL,
java.util.Map<java.lang.String,java.lang.Object> fields) |
|
void |
removeListener(OortObject.Listener<T> listener) |
|
void |
removeListeners() |
Removes all listeners.
|
protected java.lang.Object |
serialize(T object) |
|
T |
setAndShare(T newObject) |
Deprecated.
use
setAndShare(Object, Result) instead |
void |
setAndShare(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.
|
java.lang.String |
toString() |
public static final java.lang.String OORT_OBJECTS_CHANNEL
protected final org.slf4j.Logger logger
public OortObject(Oort oort, java.lang.String name, OortObject.Factory<T> factory)
protected void doStart() throws java.lang.Exception
doStart
in class org.eclipse.jetty.util.component.AbstractLifeCycle
java.lang.Exception
protected void doStop() throws java.lang.Exception
doStop
in class org.eclipse.jetty.util.component.AbstractLifeCycle
java.lang.Exception
public void configureChannel(org.cometd.bayeux.server.ConfigurableServerChannel channel)
configureChannel
in interface org.cometd.bayeux.server.ConfigurableServerChannel.Initializer
channel
- the channel to configuregetChannelName()
public java.lang.String getName()
public OortObject.Factory<T> getFactory()
public org.cometd.bayeux.server.LocalSession getLocalSession()
public java.lang.String getChannelName()
name
.configureChannel(ConfigurableServerChannel)
@Deprecated public T setAndShare(T newObject)
setAndShare(Object, Result)
insteadBlocking version of setAndShare(Object, Result)
, but deprecated.
This method will be removed in a future release.
newObject
- the new object to setpublic void setAndShare(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.
Setting an object triggers notification of OortObject.Listener
s, both on this node and on remote nodes.
The object is guaranteed to be set not when this method returns,
but when the OortObject.Result
parameter is notified.
newObject
- the new object to setcallback
- the callback invoked with the old object,
or null
if there is no interest in the old objectprotected java.lang.Object serialize(T object)
protected java.lang.Object deserialize(java.lang.Object object)
protected OortObject.Info<T> newInfo(T local)
public void cometJoined(Oort.CometListener.Event event)
Oort.CometListener
cometJoined
in interface Oort.CometListener
event
- the comet eventpublic void cometLeft(Oort.CometListener.Event event)
Oort.CometListener
cometLeft
in interface Oort.CometListener
event
- the comet eventpublic java.util.Iterator<OortObject.Info<T>> iterator()
iterator
in interface java.lang.Iterable<T>
OortObject.Info
known to this oort objectpublic OortObject.Info<T> getInfo(java.lang.String oortURL)
oortURL
- the oort URL used to search the corresponding OortObject.Info
OortObject.Info
with the given oort URL, or null if no such OortObject.Info
existspublic OortObject.Info<T> getInfoByObject(T object)
object
- the object used to search the corresponding OortObject.Info
OortObject.Info
whose object equals (via a possibly overridden Object.equals(Object)
)
the given object
public <R> R merge(OortObject.Merger<T,R> strategy)
OortObject.Info
s known to this oort object using the given strategy
.R
- the merge result typestrategy
- the strategy to merge the objectspublic void addListener(OortObject.Listener<T> listener)
listener
- the listener to addremoveListener(Listener)
public void removeListener(OortObject.Listener<T> listener)
listener
- the listener to removeaddListener(Listener)
public void removeListeners()
addListener(Listener)
,
removeListener(Listener)
protected void notifyUpdated(OortObject.Info<T> oldInfo, OortObject.Info<T> newInfo)
protected void notifyRemoved(OortObject.Info<T> info)
protected void onObject(java.util.Map<java.lang.String,java.lang.Object> data)
protected void pushInfo(java.lang.String oortURL, java.util.Map<java.lang.String,java.lang.Object> fields)
protected void pullInfo(java.lang.String oortURL)
protected java.util.Collection<OortObject.Info<T>> getInfos()
public java.lang.String toString()
toString
in class java.lang.Object
Copyright © 2008–2017 The CometD Project. All rights reserved.