mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 06:39:54 +01:00
Merge branch '2077-anything-to-send' into '1802-sync-via-removable-storage'
Add DB method for checking whether there's anything to send See merge request briar/briar!1485
This commit is contained in:
@@ -118,6 +118,18 @@ public interface DatabaseComponent extends TransactionManager {
|
|||||||
KeySetId addTransportKeys(Transaction txn, PendingContactId p,
|
KeySetId addTransportKeys(Transaction txn, PendingContactId p,
|
||||||
TransportKeys k) throws DbException;
|
TransportKeys k) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there are any acks or messages to send to the given
|
||||||
|
* contact over a transport with the given maximum latency.
|
||||||
|
* <p/>
|
||||||
|
* Read-only.
|
||||||
|
*
|
||||||
|
* @param eager True if messages that are not yet due for retransmission
|
||||||
|
* should be included
|
||||||
|
*/
|
||||||
|
boolean containsAnythingToSend(Transaction txn, ContactId c,
|
||||||
|
int maxLatency, boolean eager) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given contact for the given
|
* Returns true if the database contains the given contact for the given
|
||||||
* local pseudonym.
|
* local pseudonym.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.api.plugin.file;
|
package org.briarproject.bramble.api.plugin.file;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
|
|
||||||
@@ -37,4 +38,9 @@ public interface RemovableDriveManager {
|
|||||||
* ignored.
|
* ignored.
|
||||||
*/
|
*/
|
||||||
RemovableDriveTask startWriterTask(ContactId c, TransportProperties p);
|
RemovableDriveTask startWriterTask(ContactId c, TransportProperties p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there is anything to send to the given contact.
|
||||||
|
*/
|
||||||
|
boolean isWriterTaskNeeded(ContactId c) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,18 @@ interface Database<T> {
|
|||||||
KeySetId addTransportKeys(T txn, PendingContactId p, TransportKeys k)
|
KeySetId addTransportKeys(T txn, PendingContactId p, TransportKeys k)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there are any acks or messages to send to the given
|
||||||
|
* contact over a transport with the given maximum latency.
|
||||||
|
* <p/>
|
||||||
|
* Read-only.
|
||||||
|
*
|
||||||
|
* @param eager True if messages that are not yet due for retransmission
|
||||||
|
* should be included
|
||||||
|
*/
|
||||||
|
boolean containsAnythingToSend(T txn, ContactId c, int maxLatency,
|
||||||
|
boolean eager) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given contact for the given
|
* Returns true if the database contains the given contact for the given
|
||||||
* local pseudonym.
|
* local pseudonym.
|
||||||
|
|||||||
@@ -341,6 +341,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
return db.addTransportKeys(txn, p, k);
|
return db.addTransportKeys(txn, p, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAnythingToSend(Transaction transaction, ContactId c,
|
||||||
|
int maxLatency, boolean eager) throws DbException {
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
if (!db.containsContact(txn, c))
|
||||||
|
throw new NoSuchContactException();
|
||||||
|
return db.containsAnythingToSend(txn, c, maxLatency, eager);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsContact(Transaction transaction, AuthorId remote,
|
public boolean containsContact(Transaction transaction, AuthorId remote,
|
||||||
AuthorId local) throws DbException {
|
AuthorId local) throws DbException {
|
||||||
|
|||||||
@@ -1127,6 +1127,55 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAnythingToSend(Connection txn, ContactId c,
|
||||||
|
int maxLatency, boolean eager) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT NULL FROM statuses"
|
||||||
|
+ " WHERE contactId = ? AND ack = TRUE";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
boolean acksToSend = rs.next();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
if (acksToSend) return true;
|
||||||
|
if (eager) {
|
||||||
|
sql = "SELECT NULL from statuses"
|
||||||
|
+ " WHERE contactId = ? AND state = ?"
|
||||||
|
+ " AND groupShared = TRUE AND messageShared = TRUE"
|
||||||
|
+ " AND deleted = FALSE AND seen = FALSE";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setInt(2, DELIVERED.getValue());
|
||||||
|
} else {
|
||||||
|
long now = clock.currentTimeMillis();
|
||||||
|
long eta = now + maxLatency;
|
||||||
|
sql = "SELECT NULL FROM statuses"
|
||||||
|
+ " WHERE contactId = ? AND state = ?"
|
||||||
|
+ " AND groupShared = TRUE AND messageShared = TRUE"
|
||||||
|
+ " AND deleted = FALSE AND seen = FALSE"
|
||||||
|
+ " AND (expiry <= ? OR eta > ?)";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setInt(2, DELIVERED.getValue());
|
||||||
|
ps.setLong(3, now);
|
||||||
|
ps.setLong(4, eta);
|
||||||
|
}
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
boolean messagesToSend = rs.next();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return messagesToSend;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsContact(Connection txn, AuthorId remote,
|
public boolean containsContact(Connection txn, AuthorId remote,
|
||||||
AuthorId local) throws DbException {
|
AuthorId local) throws DbException {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.briarproject.bramble.plugin.file;
|
package org.briarproject.bramble.plugin.file;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.file.RemovableDriveManager;
|
import org.briarproject.bramble.api.plugin.file.RemovableDriveManager;
|
||||||
@@ -14,12 +16,15 @@ import javax.annotation.concurrent.GuardedBy;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.plugin.file.RemovableDrivePluginFactory.MAX_LATENCY;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class RemovableDriveManagerImpl
|
class RemovableDriveManagerImpl
|
||||||
implements RemovableDriveManager, RemovableDriveTaskRegistry {
|
implements RemovableDriveManager, RemovableDriveTaskRegistry {
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
private final DatabaseComponent db;
|
||||||
private final RemovableDriveTaskFactory taskFactory;
|
private final RemovableDriveTaskFactory taskFactory;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
@@ -30,8 +35,9 @@ class RemovableDriveManagerImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RemovableDriveManagerImpl(@IoExecutor Executor ioExecutor,
|
RemovableDriveManagerImpl(@IoExecutor Executor ioExecutor,
|
||||||
RemovableDriveTaskFactory taskFactory) {
|
DatabaseComponent db, RemovableDriveTaskFactory taskFactory) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
|
this.db = db;
|
||||||
this.taskFactory = taskFactory;
|
this.taskFactory = taskFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +80,12 @@ class RemovableDriveManagerImpl
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWriterTaskNeeded(ContactId c) throws DbException {
|
||||||
|
return db.transactionWithResult(true, txn ->
|
||||||
|
db.containsAnythingToSend(txn, c, MAX_LATENCY, true));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeReader(RemovableDriveTask task) {
|
public void removeReader(RemovableDriveTask task) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.I
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class RemovableDrivePluginFactory implements SimplexPluginFactory {
|
public class RemovableDrivePluginFactory implements SimplexPluginFactory {
|
||||||
|
|
||||||
private static final int MAX_LATENCY = (int) DAYS.toMillis(14);
|
static final int MAX_LATENCY = (int) DAYS.toMillis(14);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RemovableDrivePluginFactory() {
|
RemovableDrivePluginFactory() {
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
@@ -222,21 +223,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message, DELIVERED, true, false, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The contact has not seen the message, so it should be sendable
|
// The contact has not seen the message, so it should be sendable
|
||||||
Collection<MessageId> ids =
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendLazily(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Changing the status to seen = true should make the message unsendable
|
// Changing the status to seen = true should make the message unsendable
|
||||||
db.raiseSeenFlag(txn, contactId, messageId);
|
db.raiseSeenFlag(txn, contactId, messageId);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendEagerly(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendLazily(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -256,37 +249,23 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message, UNKNOWN, true, false, null);
|
db.addMessage(txn, message, UNKNOWN, true, false, null);
|
||||||
|
|
||||||
// The message has not been validated, so it should not be sendable
|
// The message has not been validated, so it should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
assertNothingToSendLazily(db, txn);
|
||||||
ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendEagerly(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Marking the message delivered should make it sendable
|
// Marking the message delivered should make it sendable
|
||||||
db.setMessageState(txn, messageId, DELIVERED);
|
db.setMessageState(txn, messageId, DELIVERED);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendLazily(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Marking the message invalid should make it unsendable
|
// Marking the message invalid should make it unsendable
|
||||||
db.setMessageState(txn, messageId, INVALID);
|
db.setMessageState(txn, messageId, INVALID);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Marking the message pending should make it unsendable
|
// Marking the message pending should make it unsendable
|
||||||
db.setMessageState(txn, messageId, PENDING);
|
db.setMessageState(txn, messageId, PENDING);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -305,45 +284,28 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message, DELIVERED, true, false, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The group is invisible, so the message should not be sendable
|
// The group is invisible, so the message should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
assertNothingToSendLazily(db, txn);
|
||||||
ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendEagerly(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Making the group visible should not make the message sendable
|
// Making the group visible should not make the message sendable
|
||||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Sharing the group should make the message sendable
|
// Sharing the group should make the message sendable
|
||||||
db.setGroupVisibility(txn, contactId, groupId, true);
|
db.setGroupVisibility(txn, contactId, groupId, true);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
assertOneMessageToSendLazily(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Unsharing the group should make the message unsendable
|
// Unsharing the group should make the message unsendable
|
||||||
db.setGroupVisibility(txn, contactId, groupId, false);
|
db.setGroupVisibility(txn, contactId, groupId, false);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Making the group invisible should make the message unsendable
|
// Making the group invisible should make the message unsendable
|
||||||
db.removeGroupVisibility(txn, contactId, groupId);
|
db.removeGroupVisibility(txn, contactId, groupId);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -363,21 +325,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message, DELIVERED, false, false, null);
|
db.addMessage(txn, message, DELIVERED, false, false, null);
|
||||||
|
|
||||||
// The message is not shared, so it should not be sendable
|
// The message is not shared, so it should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
assertNothingToSendLazily(db, txn);
|
||||||
ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendEagerly(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// Sharing the message should make it sendable
|
// Sharing the message should make it sendable
|
||||||
db.setMessageShared(txn, messageId, true);
|
db.setMessageShared(txn, messageId, true);
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendLazily(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -397,19 +351,17 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message, DELIVERED, true, false, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The message is sendable, but too large to send
|
// The message is sendable, but too large to send
|
||||||
|
assertOneMessageToSendLazily(db, txn);
|
||||||
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
Collection<MessageId> ids =
|
Collection<MessageId> ids =
|
||||||
db.getMessagesToSend(txn, contactId, message.getRawLength() - 1,
|
db.getMessagesToSend(txn, contactId, message.getRawLength() - 1,
|
||||||
MAX_LATENCY);
|
MAX_LATENCY);
|
||||||
assertTrue(ids.isEmpty());
|
assertTrue(ids.isEmpty());
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
// The message is just the right size to send
|
// The message is just the right size to send
|
||||||
ids = db.getMessagesToSend(txn, contactId, message.getRawLength(),
|
ids = db.getMessagesToSend(txn, contactId, message.getRawLength(),
|
||||||
MAX_LATENCY);
|
MAX_LATENCY);
|
||||||
assertEquals(singletonList(messageId), ids);
|
assertEquals(singletonList(messageId), ids);
|
||||||
assertEquals(message.getRawLength(),
|
|
||||||
db.getUnackedMessageBytesToSend(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -427,6 +379,12 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||||
|
|
||||||
|
// Initially there should be nothing to send
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
|
|
||||||
// Add some messages to ack
|
// Add some messages to ack
|
||||||
Message message1 = getMessage(groupId);
|
Message message1 = getMessage(groupId);
|
||||||
MessageId messageId1 = message1.getId();
|
MessageId messageId1 = message1.getId();
|
||||||
@@ -434,6 +392,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
|
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
// Both message IDs should be returned
|
// Both message IDs should be returned
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
Collection<MessageId> ids = db.getMessagesToAck(txn, contactId, 1234);
|
Collection<MessageId> ids = db.getMessagesToAck(txn, contactId, 1234);
|
||||||
assertEquals(asList(messageId, messageId1), ids);
|
assertEquals(asList(messageId, messageId1), ids);
|
||||||
|
|
||||||
@@ -441,6 +403,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.lowerAckFlag(txn, contactId, asList(messageId, messageId1));
|
db.lowerAckFlag(txn, contactId, asList(messageId, messageId1));
|
||||||
|
|
||||||
// Both message IDs should have been removed
|
// Both message IDs should have been removed
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
assertEquals(emptyList(), db.getMessagesToAck(txn,
|
assertEquals(emptyList(), db.getMessagesToAck(txn,
|
||||||
contactId, 1234));
|
contactId, 1234));
|
||||||
|
|
||||||
@@ -449,6 +415,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.raiseAckFlag(txn, contactId, messageId1);
|
db.raiseAckFlag(txn, contactId, messageId1);
|
||||||
|
|
||||||
// Both message IDs should be returned
|
// Both message IDs should be returned
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
ids = db.getMessagesToAck(txn, contactId, 1234);
|
ids = db.getMessagesToAck(txn, contactId, 1234);
|
||||||
assertEquals(asList(messageId, messageId1), ids);
|
assertEquals(asList(messageId, messageId1), ids);
|
||||||
|
|
||||||
@@ -469,22 +439,25 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, false, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Retrieve the message from the database and mark it as sent
|
// The message should be sendable via lazy or eager retransmission
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
assertOneMessageToSendLazily(db, txn);
|
||||||
ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
|
// Mark the message as sent
|
||||||
db.updateExpiryTimeAndEta(txn, contactId, messageId, MAX_LATENCY);
|
db.updateExpiryTimeAndEta(txn, contactId, messageId, MAX_LATENCY);
|
||||||
|
|
||||||
// The message should no longer be sendable
|
// The message should no longer be sendable via lazy retransmission,
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
// but it should still be sendable via eager retransmission
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendLazily(db, txn);
|
||||||
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
|
|
||||||
// Pretend that the message was acked
|
// Mark the message as acked
|
||||||
db.raiseSeenFlag(txn, contactId, messageId);
|
db.raiseSeenFlag(txn, contactId, messageId);
|
||||||
|
|
||||||
// The message still should not be sendable
|
// The message still should not be sendable via lazy or eager
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
// retransmission
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendLazily(db, txn);
|
||||||
|
assertNothingToSendEagerly(db, txn);
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -1957,11 +1930,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
||||||
|
|
||||||
// The message should be sendable
|
// The message should be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
assertOneMessageToSendLazily(db, txn);
|
||||||
ONE_MEGABYTE, MAX_LATENCY);
|
assertOneMessageToSendEagerly(db, txn);
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertEquals(singletonList(messageId), ids);
|
|
||||||
|
|
||||||
// The message should be available
|
// The message should be available
|
||||||
Message m = db.getMessage(txn, messageId);
|
Message m = db.getMessage(txn, messageId);
|
||||||
@@ -1977,10 +1947,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
||||||
|
|
||||||
// The message should not be sendable
|
// The message should not be sendable
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
assertNothingToSendLazily(db, txn);
|
||||||
assertTrue(ids.isEmpty());
|
assertNothingToSendEagerly(db, txn);
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
|
|
||||||
// Requesting the message should throw an exception
|
// Requesting the message should throw an exception
|
||||||
try {
|
try {
|
||||||
@@ -2609,6 +2577,50 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
deleteTestDirectory(testDir);
|
deleteTestDirectory(testDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertNothingToSendLazily(Database<Connection> db,
|
||||||
|
Connection txn) throws Exception {
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
Collection<MessageId> ids =
|
||||||
|
db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
||||||
|
assertTrue(ids.isEmpty());
|
||||||
|
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
||||||
|
assertTrue(ids.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOneMessageToSendLazily(Database<Connection> db,
|
||||||
|
Connection txn) throws Exception {
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
|
||||||
|
Collection<MessageId> ids =
|
||||||
|
db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
||||||
|
assertEquals(singletonList(messageId), ids);
|
||||||
|
ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
|
||||||
|
assertEquals(singletonList(messageId), ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNothingToSendEagerly(Database<Connection> db,
|
||||||
|
Connection txn) throws Exception {
|
||||||
|
assertFalse(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
|
Map<MessageId, Integer> unacked =
|
||||||
|
db.getUnackedMessagesToSend(txn, contactId);
|
||||||
|
assertTrue(unacked.isEmpty());
|
||||||
|
assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOneMessageToSendEagerly(Database<Connection> db,
|
||||||
|
Connection txn) throws Exception {
|
||||||
|
assertTrue(
|
||||||
|
db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
|
||||||
|
Map<MessageId, Integer> unacked =
|
||||||
|
db.getUnackedMessagesToSend(txn, contactId);
|
||||||
|
assertEquals(singleton(messageId), unacked.keySet());
|
||||||
|
assertEquals(message.getRawLength(), unacked.get(messageId).intValue());
|
||||||
|
assertEquals(message.getRawLength(),
|
||||||
|
db.getUnackedMessageBytesToSend(txn, contactId));
|
||||||
|
}
|
||||||
|
|
||||||
private static class StoppedClock implements Clock {
|
private static class StoppedClock implements Clock {
|
||||||
|
|
||||||
private final long time;
|
private final long time;
|
||||||
|
|||||||
Reference in New Issue
Block a user