diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
index 0d055641a..f8e9d5a69 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
@@ -118,6 +118,18 @@ public interface DatabaseComponent extends TransactionManager {
KeySetId addTransportKeys(Transaction txn, PendingContactId p,
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.
+ *
+ * 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
* local pseudonym.
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java
index cc14a08bb..8c74497b0 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java
@@ -1,6 +1,7 @@
package org.briarproject.bramble.api.plugin.file;
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.properties.TransportProperties;
@@ -37,4 +38,9 @@ public interface RemovableDriveManager {
* ignored.
*/
RemovableDriveTask startWriterTask(ContactId c, TransportProperties p);
+
+ /**
+ * Returns true if there is anything to send to the given contact.
+ */
+ boolean isWriterTaskNeeded(ContactId c) throws DbException;
}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
index 64f54f19b..20afbb374 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
@@ -162,6 +162,18 @@ interface Database {
KeySetId addTransportKeys(T txn, PendingContactId p, 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.
+ *
+ * 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
* local pseudonym.
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
index c92245acd..9030e2c60 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
@@ -341,6 +341,15 @@ class DatabaseComponentImpl implements DatabaseComponent {
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
public boolean containsContact(Transaction transaction, AuthorId remote,
AuthorId local) throws DbException {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
index c77010b82..a9b42e235 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
@@ -1127,6 +1127,55 @@ abstract class JdbcDatabase implements Database {
}
}
+ @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
public boolean containsContact(Connection txn, AuthorId remote,
AuthorId local) throws DbException {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java
index 78490a045..2c96d5d53 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java
@@ -1,6 +1,8 @@
package org.briarproject.bramble.plugin.file;
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.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.file.RemovableDriveManager;
@@ -14,12 +16,15 @@ import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
+import static org.briarproject.bramble.plugin.file.RemovableDrivePluginFactory.MAX_LATENCY;
+
@ThreadSafe
@NotNullByDefault
class RemovableDriveManagerImpl
implements RemovableDriveManager, RemovableDriveTaskRegistry {
private final Executor ioExecutor;
+ private final DatabaseComponent db;
private final RemovableDriveTaskFactory taskFactory;
private final Object lock = new Object();
@@ -30,8 +35,9 @@ class RemovableDriveManagerImpl
@Inject
RemovableDriveManagerImpl(@IoExecutor Executor ioExecutor,
- RemovableDriveTaskFactory taskFactory) {
+ DatabaseComponent db, RemovableDriveTaskFactory taskFactory) {
this.ioExecutor = ioExecutor;
+ this.db = db;
this.taskFactory = taskFactory;
}
@@ -74,6 +80,12 @@ class RemovableDriveManagerImpl
return created;
}
+ @Override
+ public boolean isWriterTaskNeeded(ContactId c) throws DbException {
+ return db.transactionWithResult(true, txn ->
+ db.containsAnythingToSend(txn, c, MAX_LATENCY, true));
+ }
+
@Override
public void removeReader(RemovableDriveTask task) {
synchronized (lock) {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java
index 6f1ad7564..d0bc374ed 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java
@@ -17,7 +17,7 @@ import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.I
@NotNullByDefault
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
RemovableDrivePluginFactory() {
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
index db6b3411b..649b09369 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
@@ -57,6 +57,7 @@ import java.util.concurrent.atomic.AtomicLong;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
+import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
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);
// The contact has not seen the message, so it should be sendable
- Collection 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);
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
+ assertOneMessageToSendEagerly(db, txn);
+ assertOneMessageToSendLazily(db, txn);
// Changing the status to seen = true should make the message unsendable
db.raiseSeenFlag(txn, contactId, messageId);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendEagerly(db, txn);
+ assertNothingToSendLazily(db, txn);
db.commitTransaction(txn);
db.close();
@@ -256,37 +249,23 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message, UNKNOWN, true, false, null);
// The message has not been validated, so it should not be sendable
- Collection ids = db.getMessagesToSend(txn, contactId,
- ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Marking the message delivered should make it sendable
db.setMessageState(txn, messageId, DELIVERED);
- 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);
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
+ assertOneMessageToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
// Marking the message invalid should make it unsendable
db.setMessageState(txn, messageId, INVALID);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Marking the message pending should make it unsendable
db.setMessageState(txn, messageId, PENDING);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
db.commitTransaction(txn);
db.close();
@@ -305,45 +284,28 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message, DELIVERED, true, false, null);
// The group is invisible, so the message should not be sendable
- Collection ids = db.getMessagesToSend(txn, contactId,
- ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Making the group visible should not make the message sendable
db.addGroupVisibility(txn, contactId, groupId, false);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Sharing the group should make the message sendable
db.setGroupVisibility(txn, contactId, groupId, true);
- 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);
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
+ assertOneMessageToSendEagerly(db, txn);
+ assertOneMessageToSendLazily(db, txn);
// Unsharing the group should make the message unsendable
db.setGroupVisibility(txn, contactId, groupId, false);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Making the group invisible should make the message unsendable
db.removeGroupVisibility(txn, contactId, groupId);
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
db.commitTransaction(txn);
db.close();
@@ -363,21 +325,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message, DELIVERED, false, false, null);
// The message is not shared, so it should not be sendable
- Collection ids = db.getMessagesToSend(txn, contactId,
- ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Sharing the message should make it sendable
db.setMessageShared(txn, messageId, true);
- 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);
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
+ assertOneMessageToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
db.commitTransaction(txn);
db.close();
@@ -397,19 +351,17 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message, DELIVERED, true, false, null);
// The message is sendable, but too large to send
+ assertOneMessageToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
Collection ids =
db.getMessagesToSend(txn, contactId, message.getRawLength() - 1,
MAX_LATENCY);
assertTrue(ids.isEmpty());
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
// The message is just the right size to send
ids = db.getMessagesToSend(txn, contactId, message.getRawLength(),
MAX_LATENCY);
assertEquals(singletonList(messageId), ids);
- assertEquals(message.getRawLength(),
- db.getUnackedMessageBytesToSend(txn, contactId));
db.commitTransaction(txn);
db.close();
@@ -427,6 +379,12 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addGroup(txn, group);
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
Message message1 = getMessage(groupId);
MessageId messageId1 = message1.getId();
@@ -434,6 +392,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
// Both message IDs should be returned
+ assertTrue(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
+ assertTrue(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
Collection ids = db.getMessagesToAck(txn, contactId, 1234);
assertEquals(asList(messageId, messageId1), ids);
@@ -441,6 +403,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.lowerAckFlag(txn, contactId, asList(messageId, messageId1));
// 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,
contactId, 1234));
@@ -449,6 +415,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.raiseAckFlag(txn, contactId, messageId1);
// 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);
assertEquals(asList(messageId, messageId1), ids);
@@ -469,22 +439,25 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, false, null);
- // Retrieve the message from the database and mark it as sent
- Collection ids = db.getMessagesToSend(txn, contactId,
- ONE_MEGABYTE, MAX_LATENCY);
- assertEquals(singletonList(messageId), ids);
+ // The message should be sendable via lazy or eager retransmission
+ assertOneMessageToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
+
+ // Mark the message as sent
db.updateExpiryTimeAndEta(txn, contactId, messageId, MAX_LATENCY);
- // The message should no longer be sendable
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
+ // The message should no longer be sendable via lazy retransmission,
+ // but it should still be sendable via eager retransmission
+ assertNothingToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
- // Pretend that the message was acked
+ // Mark the message as acked
db.raiseSeenFlag(txn, contactId, messageId);
- // The message still should not be sendable
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
+ // The message still should not be sendable via lazy or eager
+ // retransmission
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
db.commitTransaction(txn);
db.close();
@@ -1957,11 +1930,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
// The message should be sendable
- Collection 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);
+ assertOneMessageToSendLazily(db, txn);
+ assertOneMessageToSendEagerly(db, txn);
// The message should be available
Message m = db.getMessage(txn, messageId);
@@ -1977,10 +1947,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
// The message should not be sendable
- ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
- assertTrue(ids.isEmpty());
- ids = db.getMessagesToOffer(txn, contactId, 100, MAX_LATENCY);
- assertTrue(ids.isEmpty());
+ assertNothingToSendLazily(db, txn);
+ assertNothingToSendEagerly(db, txn);
// Requesting the message should throw an exception
try {
@@ -2609,6 +2577,50 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
deleteTestDirectory(testDir);
}
+ private void assertNothingToSendLazily(Database db,
+ Connection txn) throws Exception {
+ assertFalse(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
+ Collection 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 db,
+ Connection txn) throws Exception {
+ assertTrue(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, false));
+ Collection 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 db,
+ Connection txn) throws Exception {
+ assertFalse(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
+ Map unacked =
+ db.getUnackedMessagesToSend(txn, contactId);
+ assertTrue(unacked.isEmpty());
+ assertEquals(0, db.getUnackedMessageBytesToSend(txn, contactId));
+ }
+
+ private void assertOneMessageToSendEagerly(Database db,
+ Connection txn) throws Exception {
+ assertTrue(
+ db.containsAnythingToSend(txn, contactId, MAX_LATENCY, true));
+ Map 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 final long time;