Tom,
CDO 2.0 has several mechansims to catch up with remote changes. They
differ in the amount of change information being delivered and thus in
the burden put on the network:
1) CDOSessionInvalidationEvent is the oldest and simplest form. The
event is emitted to registered IListeners of a CDOSession *if*
PassiveUpdate is enabled for the session.
/**
* An event that is emitted to registered {@link IListener listeners} of a {@link CDOSession} if
* {@link CDOSession#setPassiveUpdateEnabled(boolean) passive update} is enabled for the session.
*
* @author Eike Stepper
* @see CDOInvalidationNotification
* @see CDOChangeSubscriptionPolicy
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface CDOSessionInvalidationEvent extends CDOSessionEvent
{
public static final long LOCAL_ROLLBACK = CDORevision.UNSPECIFIED_DATE;
/**
* Returns the transaction that was committed and thereby caused this event to be emitted if this transaction is
* local, or <code>null</code> if the transaction was remote.
*/
public CDOView getView();
/**
* Returns the time stamp of the server transaction if this event was sent as a result of a successfully committed
* transaction or <code>LOCAL_ROLLBACK</code> if this event was sent due to a local rollback.
*/
public long getTimeStamp();
/**
* Returns a set of the {@link CDOID CDOIDs} and versions of the modified objects.
*/
public Set<CDOIDAndVersion> getDirtyOIDs();
/**
* Returns a collection of the {@link CDOID CDOIDs} of the removed objects.
*
* @since 2.0
*/
public Collection<CDOID> getDetachedObjects();
} |
2) CDOInvalidationNotification is a *custom* EMF notification that is
emitted to adapters of the EObjects in a CDOView *if*
InvalidationNotification is enabled for the view. Since the
notifications are constructed out of the information in a
CDOSessionInvalidationEvent (i.e. CDOIDs) they don't carry detailed
change deltas. All the Notification methods related to change deltas
throw UOEs.
/**
* A custom EMF {@link Notification notification} that is emitted to {@link Adapter adapters} of the objects in a
* {@link CDOView view} if {@link CDOView#setInvalidationNotificationEnabled(boolean) invalidation notification} is
* enabled for the view. Since the notifications are constructed out of the information in a
* {@link CDOSessionInvalidationEvent} (i.e. {@link CDOID CDOIDs}) they don't carry detailed change deltas. All the
* methods related to change deltas throw {@link UnsupportedOperationException UnsupportedOperationExceptions}.
*
* @author Simon McDuff
* @see CDOSessionInvalidationEvent
* @see CDOChangeSubscriptionPolicy
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface CDOInvalidationNotification extends Notification
{
public static final int INVALIDATE = EVENT_TYPE_COUNT + 1;
} |
3) CDOChangeSubscriptionPolicy a
is the newest form (only in 2.0) and the one that delivers the most
detailed information about the actual change. The change information is
delivered to object adapters. To compensate the bandwidth burden of the
change info per object you must exactly specify for which objects it is
provides. With one of the shipped policies or an own one you can do
this per view:
/**
* Specifies a change subscription policy.
* <p>
* To activate a policy, you must do the following: <br>
* <code>view.setChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL);</code>
* <p>
* To register an object, you must add an adapter to the object in which you are interested:<br>
* <code>eObject.eAdapters().add(myAdapter);</code>
* <p>
* By activating this feature, each object having at least one adapter that matches the current policy will be
* registered with the server and will be notified for each change occurring in the scope of any other transaction.
* <p>
* {@link CDOChangeSubscriptionPolicy#NONE} - Disabled. <br>
* {@link CDOChangeSubscriptionPolicy#ALL} - Enabled for all adapters used.<br>
* {@link CDOChangeSubscriptionPolicy#ONLY_CDO_ADAPTER} - Enabled only for adapters that implement {@link CDOAdapter}. <br>
* Any other class that implement {@link CDOChangeSubscriptionPolicy} will enable for whatever rules defined in that
* class. <br>
* <p>
* If <code>myAdapter</code> in the above example matches the current policy, <code>eObject</code> will be registered
* with the server and you will receive all changes from other transaction.
* <p>
* When the policy is changed all objects in the cache will automatically be recalculated.
* <p>
* You can subscribe to temporary objects. Even if you cannot receive notifications from other {@link CDOTransaction}
* for these because they are only local to you, at commit time these objects will be registered automatically.
* <p>
* <b>Note:</b> It can be used with <code>CDOSession.setPassiveUpdate(false)</code>. In this case, it will receive
* changes without having the objects changed.
*
* @author Simon McDuff
* @since 2.0
*/
public interface CDOChangeSubscriptionPolicy
{
public static final CDOChangeSubscriptionPolicy NONE = new CDOChangeSubscriptionPolicy()
{
public boolean shouldSubscribe(EObject eObject, Adapter adapter)
{
return false;
}
};
public static final CDOChangeSubscriptionPolicy ONLY_CDO_ADAPTER = new CDOChangeSubscriptionPolicy()
{
public boolean shouldSubscribe(EObject eObject, Adapter adapter)
{
return adapter instanceof CDOAdapter;
}
};
public static final CDOChangeSubscriptionPolicy ALL = new CDOChangeSubscriptionPolicy()
{
public boolean shouldSubscribe(EObject eObject, Adapter adapter)
{
return true;
}
};
public boolean shouldSubscribe(EObject eObject, Adapter adapter);
} |
Cheers
/Eike
Tom Crockett schrieb:
When a remote client makes a change and commits it, it
seems that the CDOInvalidationNotification which other clients receive
contains only the notifier object, and no information about which
feature changed, or the previous or new values. It's left to me to
write diff'ing code to figure that out ;) Is this going to be fixed in
future versions, or has it already been fixed on trunk? It'd be nice if
the type of the notification was INVALIDATE_ADD, INVALIDATE_ADD_MANY,
INVALIDATE_REMOVE, INVALIDATE_SET, etc., so that client code could
decide whether to forward it as a regular ADD, ADD_MANY, etc.
notification, or to do something like wrap it in a write transaction
(if they are using EMF Transactions, which we are.)
|