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
* given transport, replacing any existing properties, unless an update
* with an equal or higher version number has already been received from
* the contact.
* given transport, replacing any existing properties, and returns true,
* unless an update with an equal or higher version number has already been
* received from the contact.
* <p>
* 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;
/**
* Sets the retention time of the given contact's database, unless an
* update with an equal or higher version number has already been received
* from the contact.
* Sets the retention time of the given contact's database and returns
* true, unless an update with an equal or higher version number has
* already been received from the contact.
* <p>
* 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;
/**
@@ -761,17 +761,17 @@ interface Database<T> {
throws DbException;
/**
* Updates the groups to which the given contact subscribes, unless an
* update with an equal or higher version number has already been received
* from the contact.
* Updates the groups to which the given contact subscribes and returns
* true, unless an update with an equal or higher version number has
* already been received from the contact.
* <p>
* 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;
/**
* 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.
* <p>
* Locking: retention write.
@@ -780,7 +780,7 @@ interface Database<T> {
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.
* <p>
* Locking: subscription write.
@@ -789,7 +789,7 @@ interface Database<T> {
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.
* <p>
* Locking: transport write.

View File

@@ -1613,6 +1613,7 @@ DatabaseCleaner.Callback {
public void receiveRetentionUpdate(ContactId c, RetentionUpdate u)
throws DbException {
boolean updated;
contactLock.readLock().lock();
try {
retentionLock.writeLock().lock();
@@ -1621,7 +1622,7 @@ DatabaseCleaner.Callback {
try {
if(!db.containsContact(txn, c))
throw new NoSuchContactException();
db.setRetentionTime(txn, c, u.getRetentionTime(),
updated = db.setRetentionTime(txn, c, u.getRetentionTime(),
u.getVersion());
db.commitTransaction(txn);
} catch(DbException e) {
@@ -1634,7 +1635,7 @@ DatabaseCleaner.Callback {
} finally {
contactLock.readLock().unlock();
}
callListeners(new RemoteRetentionTimeUpdatedEvent(c));
if(updated) callListeners(new RemoteRetentionTimeUpdatedEvent(c));
}
public void receiveSubscriptionAck(ContactId c, SubscriptionAck a)
@@ -1663,6 +1664,7 @@ DatabaseCleaner.Callback {
public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate u)
throws DbException {
boolean updated;
contactLock.readLock().lock();
try {
subscriptionLock.writeLock().lock();
@@ -1671,7 +1673,9 @@ DatabaseCleaner.Callback {
try {
if(!db.containsContact(txn, c))
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);
} catch(DbException e) {
db.abortTransaction(txn);
@@ -1683,7 +1687,7 @@ DatabaseCleaner.Callback {
} finally {
contactLock.readLock().unlock();
}
callListeners(new RemoteSubscriptionsUpdatedEvent(c));
if(updated) callListeners(new RemoteSubscriptionsUpdatedEvent(c));
}
public void receiveTransportAck(ContactId c, TransportAck a)
@@ -1715,6 +1719,7 @@ DatabaseCleaner.Callback {
public void receiveTransportUpdate(ContactId c, TransportUpdate u)
throws DbException {
boolean updated;
contactLock.readLock().lock();
try {
transportLock.writeLock().lock();
@@ -1723,8 +1728,10 @@ DatabaseCleaner.Callback {
try {
if(!db.containsContact(txn, c))
throw new NoSuchContactException();
db.setRemoteProperties(txn, c, u.getId(), u.getProperties(),
u.getVersion());
TransportId t = u.getId();
TransportProperties p = u.getProperties();
long version = u.getVersion();
updated = db.setRemoteProperties(txn, c, t, p, version);
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
@@ -1736,7 +1743,8 @@ DatabaseCleaner.Callback {
} finally {
contactLock.readLock().unlock();
}
callListeners(new RemoteTransportsUpdatedEvent(c, u.getId()));
if(updated)
callListeners(new RemoteTransportsUpdatedEvent(c, u.getId()));
}
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
TransportProperties p = new TransportProperties(
Collections.singletonMap("foo", "bar"));
db.setRemoteProperties(txn, contactId, transportId, p, 1);
assertTrue(db.setRemoteProperties(txn, contactId, transportId, p, 1));
assertEquals(Collections.singletonMap(contactId, p),
db.getRemoteProperties(txn, transportId));
// Replace the transport properties with version 2
TransportProperties p1 = new TransportProperties(
Collections.singletonMap("baz", "bam"));
db.setRemoteProperties(txn, contactId, transportId, p1, 2);
assertTrue(db.setRemoteProperties(txn, contactId, transportId, p1, 2));
assertEquals(Collections.singletonMap(contactId, p1),
db.getRemoteProperties(txn, transportId));
// Try to replace the transport properties with version 1
TransportProperties p2 = new TransportProperties(
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
assertEquals(Collections.singletonMap(contactId, p1),