Don't broadcast events for obsolete updates.

This commit is contained in:
akwizgran
2013-04-14 15:16:18 +01:00
parent 69c55ce5f2
commit 8e9517ced0
3 changed files with 33 additions and 25 deletions

View File

@@ -715,23 +715,23 @@ interface Database<T> {
/** /**
* Updates the remote transport properties for the given contact and the * Updates the remote transport properties for the given contact and the
* given transport, replacing any existing properties, unless an update * given transport, replacing any existing properties, and returns true,
* with an equal or higher version number has already been received from * unless an update with an equal or higher version number has already been
* the contact. * received from the contact.
* <p> * <p>
* Locking: transport write. * Locking: transport write.
*/ */
void setRemoteProperties(T txn, ContactId c, TransportId t, boolean setRemoteProperties(T txn, ContactId c, TransportId t,
TransportProperties p, long version) throws DbException; TransportProperties p, long version) throws DbException;
/** /**
* Sets the retention time of the given contact's database, unless an * Sets the retention time of the given contact's database and returns
* update with an equal or higher version number has already been received * true, unless an update with an equal or higher version number has
* from the contact. * already been received from the contact.
* <p> * <p>
* Locking: retention write. * Locking: retention write.
*/ */
void setRetentionTime(T txn, ContactId c, long retention, long version) boolean setRetentionTime(T txn, ContactId c, long retention, long version)
throws DbException; throws DbException;
/** /**
@@ -761,17 +761,17 @@ interface Database<T> {
throws DbException; throws DbException;
/** /**
* Updates the groups to which the given contact subscribes, unless an * Updates the groups to which the given contact subscribes and returns
* update with an equal or higher version number has already been received * true, unless an update with an equal or higher version number has
* from the contact. * already been received from the contact.
* <p> * <p>
* Locking: subscription write. * Locking: subscription write.
*/ */
void setSubscriptions(T txn, ContactId c, Collection<Group> subs, boolean setSubscriptions(T txn, ContactId c, Collection<Group> subs,
long version) throws DbException; long version) throws DbException;
/** /**
* Records a retention ack from the given contact for the given version * Records a retention ack from the given contact for the given version,
* unless the contact has already acked an equal or higher version. * unless the contact has already acked an equal or higher version.
* <p> * <p>
* Locking: retention write. * Locking: retention write.
@@ -780,7 +780,7 @@ interface Database<T> {
throws DbException; throws DbException;
/** /**
* Records a subscription ack from the given contact for the given version * Records a subscription ack from the given contact for the given version,
* unless the contact has already acked an equal or higher version. * unless the contact has already acked an equal or higher version.
* <p> * <p>
* Locking: subscription write. * Locking: subscription write.
@@ -789,7 +789,7 @@ interface Database<T> {
throws DbException; throws DbException;
/** /**
* Records a transport ack from the give contact for the given version * Records a transport ack from the give contact for the given version,
* unless the contact has already acked an equal or higher version. * unless the contact has already acked an equal or higher version.
* <p> * <p>
* Locking: transport write. * Locking: transport write.

View File

@@ -1613,6 +1613,7 @@ DatabaseCleaner.Callback {
public void receiveRetentionUpdate(ContactId c, RetentionUpdate u) public void receiveRetentionUpdate(ContactId c, RetentionUpdate u)
throws DbException { throws DbException {
boolean updated;
contactLock.readLock().lock(); contactLock.readLock().lock();
try { try {
retentionLock.writeLock().lock(); retentionLock.writeLock().lock();
@@ -1621,7 +1622,7 @@ DatabaseCleaner.Callback {
try { try {
if(!db.containsContact(txn, c)) if(!db.containsContact(txn, c))
throw new NoSuchContactException(); throw new NoSuchContactException();
db.setRetentionTime(txn, c, u.getRetentionTime(), updated = db.setRetentionTime(txn, c, u.getRetentionTime(),
u.getVersion()); u.getVersion());
db.commitTransaction(txn); db.commitTransaction(txn);
} catch(DbException e) { } catch(DbException e) {
@@ -1634,7 +1635,7 @@ DatabaseCleaner.Callback {
} finally { } finally {
contactLock.readLock().unlock(); contactLock.readLock().unlock();
} }
callListeners(new RemoteRetentionTimeUpdatedEvent(c)); if(updated) callListeners(new RemoteRetentionTimeUpdatedEvent(c));
} }
public void receiveSubscriptionAck(ContactId c, SubscriptionAck a) public void receiveSubscriptionAck(ContactId c, SubscriptionAck a)
@@ -1663,6 +1664,7 @@ DatabaseCleaner.Callback {
public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate u) public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate u)
throws DbException { throws DbException {
boolean updated;
contactLock.readLock().lock(); contactLock.readLock().lock();
try { try {
subscriptionLock.writeLock().lock(); subscriptionLock.writeLock().lock();
@@ -1671,7 +1673,9 @@ DatabaseCleaner.Callback {
try { try {
if(!db.containsContact(txn, c)) if(!db.containsContact(txn, c))
throw new NoSuchContactException(); throw new NoSuchContactException();
db.setSubscriptions(txn, c, u.getGroups(), u.getVersion()); Collection<Group> groups = u.getGroups();
long version = u.getVersion();
updated = db.setSubscriptions(txn, c, groups, version);
db.commitTransaction(txn); db.commitTransaction(txn);
} catch(DbException e) { } catch(DbException e) {
db.abortTransaction(txn); db.abortTransaction(txn);
@@ -1683,7 +1687,7 @@ DatabaseCleaner.Callback {
} finally { } finally {
contactLock.readLock().unlock(); contactLock.readLock().unlock();
} }
callListeners(new RemoteSubscriptionsUpdatedEvent(c)); if(updated) callListeners(new RemoteSubscriptionsUpdatedEvent(c));
} }
public void receiveTransportAck(ContactId c, TransportAck a) public void receiveTransportAck(ContactId c, TransportAck a)
@@ -1715,6 +1719,7 @@ DatabaseCleaner.Callback {
public void receiveTransportUpdate(ContactId c, TransportUpdate u) public void receiveTransportUpdate(ContactId c, TransportUpdate u)
throws DbException { throws DbException {
boolean updated;
contactLock.readLock().lock(); contactLock.readLock().lock();
try { try {
transportLock.writeLock().lock(); transportLock.writeLock().lock();
@@ -1723,8 +1728,10 @@ DatabaseCleaner.Callback {
try { try {
if(!db.containsContact(txn, c)) if(!db.containsContact(txn, c))
throw new NoSuchContactException(); throw new NoSuchContactException();
db.setRemoteProperties(txn, c, u.getId(), u.getProperties(), TransportId t = u.getId();
u.getVersion()); TransportProperties p = u.getProperties();
long version = u.getVersion();
updated = db.setRemoteProperties(txn, c, t, p, version);
db.commitTransaction(txn); db.commitTransaction(txn);
} catch(DbException e) { } catch(DbException e) {
db.abortTransaction(txn); db.abortTransaction(txn);
@@ -1736,7 +1743,8 @@ DatabaseCleaner.Callback {
} finally { } finally {
contactLock.readLock().unlock(); contactLock.readLock().unlock();
} }
callListeners(new RemoteTransportsUpdatedEvent(c, u.getId())); if(updated)
callListeners(new RemoteTransportsUpdatedEvent(c, u.getId()));
} }
public void removeContact(ContactId c) throws DbException { public void removeContact(ContactId c) throws DbException {

View File

@@ -839,21 +839,21 @@ public class H2DatabaseTest extends BriarTestCase {
// Initialise the transport properties with version 1 // Initialise the transport properties with version 1
TransportProperties p = new TransportProperties( TransportProperties p = new TransportProperties(
Collections.singletonMap("foo", "bar")); Collections.singletonMap("foo", "bar"));
db.setRemoteProperties(txn, contactId, transportId, p, 1); assertTrue(db.setRemoteProperties(txn, contactId, transportId, p, 1));
assertEquals(Collections.singletonMap(contactId, p), assertEquals(Collections.singletonMap(contactId, p),
db.getRemoteProperties(txn, transportId)); db.getRemoteProperties(txn, transportId));
// Replace the transport properties with version 2 // Replace the transport properties with version 2
TransportProperties p1 = new TransportProperties( TransportProperties p1 = new TransportProperties(
Collections.singletonMap("baz", "bam")); Collections.singletonMap("baz", "bam"));
db.setRemoteProperties(txn, contactId, transportId, p1, 2); assertTrue(db.setRemoteProperties(txn, contactId, transportId, p1, 2));
assertEquals(Collections.singletonMap(contactId, p1), assertEquals(Collections.singletonMap(contactId, p1),
db.getRemoteProperties(txn, transportId)); db.getRemoteProperties(txn, transportId));
// Try to replace the transport properties with version 1 // Try to replace the transport properties with version 1
TransportProperties p2 = new TransportProperties( TransportProperties p2 = new TransportProperties(
Collections.singletonMap("quux", "etc")); Collections.singletonMap("quux", "etc"));
db.setRemoteProperties(txn, contactId, transportId, p2, 1); assertFalse(db.setRemoteProperties(txn, contactId, transportId, p2, 1));
// Version 2 of the properties should still be there // Version 2 of the properties should still be there
assertEquals(Collections.singletonMap(contactId, p1), assertEquals(Collections.singletonMap(contactId, p1),