Widened, added a workaround for a "doesn't actually break anything and is too
complex to properly fix right now" bug. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4713 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -71,8 +71,8 @@ public abstract class DEvent implements Streamable
|
||||
* @exception ObjectAccessException thrown if there is any problem applying the event to the
|
||||
* object (invalid attribute, etc.).
|
||||
*
|
||||
* @return true if the object manager should go on to notify the object's subscribers of this
|
||||
* event, false if the event should be treated silently and the subscribers should not be
|
||||
* @return true if the object manager should go on to notify the object's listeners of this
|
||||
* event, false if the event should be treated silently and the listeners should not be
|
||||
* notified.
|
||||
*/
|
||||
public abstract boolean applyToObject (DObject target)
|
||||
|
||||
@@ -26,22 +26,20 @@ import com.samskivert.util.StringUtil;
|
||||
import com.threerings.presents.Log;
|
||||
|
||||
/**
|
||||
* An entry added event is dispatched when an entry is added to a {@link
|
||||
* DSet} attribute of a distributed entry. It can also be constructed to
|
||||
* request the addition of an entry to a set and posted to the dobjmgr.
|
||||
* An entry added event is dispatched when an entry is added to a {@link DSet} attribute of a
|
||||
* distributed entry. It can also be constructed to request the addition of an entry to a set and
|
||||
* posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry added event on the specified target object
|
||||
* with the supplied set attribute name and entry to add.
|
||||
* Constructs a new entry added event on the specified target object with the supplied set
|
||||
* attribute name and entry to add.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose set we will
|
||||
* add an entry.
|
||||
* @param name the name of the attribute to which to add the specified
|
||||
* entry.
|
||||
* @param targetOid the object id of the object to whose set we will add an entry.
|
||||
* @param name the name of the attribute to which to add the specified entry.
|
||||
* @param entry the entry to add to the set attribute.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, T entry)
|
||||
@@ -50,11 +48,9 @@ public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when the distributed object already added the entry before
|
||||
* generating the event.
|
||||
* Used when the distributed object already added the entry before generating the event.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, T entry,
|
||||
boolean alreadyApplied)
|
||||
public EntryAddedEvent (int targetOid, String name, T entry, boolean alreadyApplied)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_entry = entry;
|
||||
@@ -62,8 +58,8 @@ public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryAddedEvent ()
|
||||
{
|
||||
@@ -86,7 +82,31 @@ public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
if (!_alreadyApplied) {
|
||||
boolean added = target.getSet(_name).add(_entry);
|
||||
if (!added) {
|
||||
Log.warning("Duplicate entry found [event=" + this + "].");
|
||||
// If this entry is already in the set, then don't notify our listeners of the
|
||||
// event add, because nothing was actually added; the DSet will have already
|
||||
// complained; this happens occasionally due to a race condition between client
|
||||
// object subscription and set addition, for example, the follow sequence of events
|
||||
// can take place:
|
||||
//
|
||||
// 1. SUBSCRIBE arrives from client, AccessObjectEvent posted;
|
||||
//
|
||||
// 2. addToSet() called on server, value immediately added to set and
|
||||
// EntryAddedEvent is posted;
|
||||
//
|
||||
// 3. AccessObjectEvent processed; client is added to proxy subscriber list,
|
||||
// DObject serialized and sent to client; client receives object which already has
|
||||
// the entry in the set;
|
||||
//
|
||||
// 4. EntryAddedEvent processed, client is a subscriber so it is forwarded along;
|
||||
// when it arrives at the client, we find ourselves in this situation.
|
||||
//
|
||||
// Fixing this would require either a) giving up immediate adding to the DSet when
|
||||
// an event is posted, but we add/update immediately because it makes our lives
|
||||
// *vastly* simpler in a thousand other cases, or b) doing some magic in the DSet
|
||||
// where the server "sees" the new entry added, but if the DSet is serialized
|
||||
// before the EntryAddedEvent comes through to "commit" that entry it is not
|
||||
// included. This is probably a good idea and maybe we'll do it sometime.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -111,8 +131,7 @@ public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
|
||||
protected T _entry;
|
||||
|
||||
/** Used when this event is generated on the authoritative server
|
||||
* where object changes are made immediately. This lets us know not to
|
||||
* apply ourselves when we're actually dispatched. */
|
||||
/** Used when this event is generated on the authoritative server where object changes are made
|
||||
* immediately. This lets us know not to apply ourselves when we're actually dispatched. */
|
||||
protected transient boolean _alreadyApplied;
|
||||
}
|
||||
|
||||
@@ -24,28 +24,24 @@ package com.threerings.presents.dobj;
|
||||
import com.threerings.presents.Log;
|
||||
|
||||
/**
|
||||
* An entry removed event is dispatched when an entry is removed from a
|
||||
* {@link DSet} attribute of a distributed object. It can also be
|
||||
* constructed to request the removal of an entry from a set and posted to
|
||||
* the dobjmgr.
|
||||
* An entry removed event is dispatched when an entry is removed from a {@link DSet} attribute of a
|
||||
* distributed object. It can also be constructed to request the removal of an entry from a set and
|
||||
* posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry removed event on the specified target object
|
||||
* with the supplied set attribute name and entry key to remove.
|
||||
* Constructs a new entry removed event on the specified target object with the supplied set
|
||||
* attribute name and entry key to remove.
|
||||
*
|
||||
* @param targetOid the object id of the object from whose set we will
|
||||
* remove an entry.
|
||||
* @param name the name of the attribute from which to remove the
|
||||
* specified entry.
|
||||
* @param targetOid the object id of the object from whose set we will remove an entry.
|
||||
* @param name the name of the attribute from which to remove the specified entry.
|
||||
* @param key the entry key that identifies the entry to remove.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
public EntryRemovedEvent (int targetOid, String name, Comparable key,
|
||||
T oldEntry)
|
||||
public EntryRemovedEvent (int targetOid, String name, Comparable key, T oldEntry)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_key = key;
|
||||
@@ -53,8 +49,8 @@ public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryRemovedEvent ()
|
||||
{
|
||||
@@ -88,8 +84,7 @@ public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
_oldEntry = set.removeKey(_key);
|
||||
if (_oldEntry == null) {
|
||||
// complain if there was actually nothing there
|
||||
Log.warning("No matching entry to remove [key=" + _key +
|
||||
", set=" + set + "].");
|
||||
Log.warning("No matching entry to remove [key=" + _key + ", set=" + set + "].");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -113,6 +108,7 @@ public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
protected Comparable _key;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
|
||||
@@ -26,22 +26,19 @@ import com.samskivert.util.StringUtil;
|
||||
import com.threerings.presents.Log;
|
||||
|
||||
/**
|
||||
* An entry updated event is dispatched when an entry of a {@link DSet} is
|
||||
* updated. It can also be constructed to request the update of an entry
|
||||
* and posted to the dobjmgr.
|
||||
* An entry updated event is dispatched when an entry of a {@link DSet} is updated. It can also be
|
||||
* constructed to request the update of an entry and posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry updated event on the specified target object
|
||||
* for the specified set name and with the supplied updated entry.
|
||||
* Constructs a new entry updated event on the specified target object for the specified set
|
||||
* name and with the supplied updated entry.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose set we will
|
||||
* add an entry.
|
||||
* @param name the name of the attribute in which to update the
|
||||
* specified entry.
|
||||
* @param targetOid the object id of the object to whose set we will add an entry.
|
||||
* @param name the name of the attribute in which to update the specified entry.
|
||||
* @param entry the entry to update.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
@@ -53,8 +50,8 @@ public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryUpdatedEvent ()
|
||||
{
|
||||
@@ -89,8 +86,7 @@ public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
_oldEntry = set.update(_entry);
|
||||
if (_oldEntry == null) {
|
||||
// complain if we didn't update anything
|
||||
Log.warning("No matching entry to update [entry=" + this +
|
||||
", set=" + set + "].");
|
||||
Log.warning("No matching entry to update [entry=" + this + ", set=" + set + "].");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -115,6 +111,7 @@ public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
}
|
||||
|
||||
protected T _entry;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user