Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit 1873f39

Browse files
authored
Merge pull request #553 from cloudant/534-add-seq-interval-in-changes-feed
534 add sequence interval to changes
2 parents 9dc8229 + d24821e commit 1873f39

File tree

4 files changed

+63
-11
lines changed

4 files changed

+63
-11
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
[Bluemix documentation](https://console.bluemix.net/docs/services/Cloudant/guides/iam.html#ibm-cloud-identity-and-access-management)
55
for more details.
66
- [IMPROVED] Updated documentation by replacing deprecated links with the latest Bluemix or CouchDB links.
7+
- [IMPROVED] Added `seq_interval` to improve `Changes` API throughput when replicating from
8+
a CouchDB 2.x endpoint.
79

810
# 2.0.2 (2017-06-20)
911
- [FIXED] Removed cloudant-sync-datastore-android project dependency

cloudant-sync-datastore-core/src/main/java/com/cloudant/sync/internal/mazha/CouchClient.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,6 @@ private Map<String, Object> getDefaultChangeFeedOptions() {
284284
return options;
285285
}
286286

287-
public ChangesResult changes(Object since) {
288-
return this.changes(since, null);
289-
}
290-
291287
public ChangesResult changes(Object since, Integer limit) {
292288
return this.changes(null, null, since, limit);
293289
}
@@ -306,6 +302,12 @@ public ChangesResult changes(String filterName, Map<String, String> filterParame
306302
if (limit != null) {
307303
options.put("limit", limit);
308304
}
305+
// seq_interval: improve performance and reduce load on the remote database
306+
if(limit != null) {
307+
options.put("seq_interval", limit);
308+
} else {
309+
options.put("seq_interval", 1000);
310+
}
309311
return this.changes(options);
310312
}
311313

cloudant-sync-datastore-core/src/test/java/com/cloudant/sync/internal/mazha/ChangesFeedTest.java

+44-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import com.cloudant.common.RequireRunningCouchDB;
2424

25+
import java.io.IOException;
26+
import java.net.URISyntaxException;
2527
import java.util.ArrayList;
2628
import java.util.HashMap;
2729
import java.util.List;
@@ -40,7 +42,7 @@ public void changes_dbChangesMustSuccessfullyReturn() {
4042
Object lastSeq = "0";
4143

4244
{ // Two docs changed
43-
ChangesResult changes = client.changes(lastSeq);
45+
ChangesResult changes = getChangesSince(lastSeq);
4446
Map<String, List<String>> changedRevIds = findChangedRevisionIds(changes);
4547

4648
Assert.assertThat(changedRevIds.size(), is(equalTo(2)));
@@ -54,7 +56,7 @@ public void changes_dbChangesMustSuccessfullyReturn() {
5456
Response res3 = ClientTestUtils.createHelloWorldDoc(client);
5557

5658
{ // One doc changed
57-
ChangesResult changes = client.changes(lastSeq);
59+
ChangesResult changes = getChangesSince(lastSeq);
5860
Map<String, List<String>> changedRevIds = findChangedRevisionIds(changes);
5961

6062
Assert.assertThat(changedRevIds.size(), is(equalTo(1)));
@@ -65,7 +67,7 @@ public void changes_dbChangesMustSuccessfullyReturn() {
6567
}
6668

6769
{ // No changes
68-
ChangesResult changes = client.changes(lastSeq);
70+
ChangesResult changes = getChangesSince(lastSeq);
6971
Assert.assertTrue(changes.size() == 0);
7072
}
7173
}
@@ -85,21 +87,52 @@ public Map<String, List<String>> findChangedRevisionIds(ChangesResult changesRes
8587
@Test(expected = NoResourceException.class)
8688
public void changes_dbNotExist_exception() {
8789
client.deleteDb();
88-
client.changes("1");
90+
getChangesSince("1");
8991
}
9092

9193
@Test
9294
public void changes_docWithConflicts_conflictsShouldBeReturned() {
9395
// Not sure how to changed conflicts yet
9496
}
9597

98+
@Test
99+
public void changes_dbChangesMustSuccessfullyReturnWithSeqInterval() throws IOException,
100+
URISyntaxException {
101+
org.junit.Assume.assumeTrue(ClientTestUtils.isCouchDBV2(client.getRootUri()));
102+
Response res1 = ClientTestUtils.createHelloWorldDoc(client);
103+
Response res2 = ClientTestUtils.createHelloWorldDoc(client);
104+
ClientTestUtils.createHelloWorldDoc(client);
105+
Object lastSeq = "0";
106+
107+
{
108+
// Use batch interval and seq_interval of 4
109+
ChangesResult changes = client.changes(lastSeq, 4);
110+
Map<String, List<String>> changedRevIds = findChangedRevisionIds(changes);
111+
112+
Assert.assertThat(changedRevIds.size(), is(equalTo(3)));
113+
Assert.assertThat(changedRevIds.keySet(), hasItems(res1.getId(), res2.getId()));
114+
Assert.assertThat(changedRevIds.get(res1.getId()), hasItem(res1.getRev()));
115+
Assert.assertThat(changedRevIds.get(res2.getId()), hasItem(res2.getRev()));
116+
// last two shouldn't have seq
117+
Assert.assertNull(changes.getResults().get(1).getSeq());
118+
Assert.assertNull(changes.getResults().get(2).getSeq());
119+
120+
lastSeq = changes.getLastSeq();
121+
}
122+
123+
{ // No changes
124+
ChangesResult changes = getChangesSince(lastSeq);
125+
Assert.assertTrue(changes.size() == 0);
126+
}
127+
}
128+
96129
@Test
97130
public void changes_dbWithConflicts_changesMustSuccessfullyReturn() {
98131
ClientTestUtils.createHelloWorldDoc(client);
99132
Object lastSeq = "0";
100133

101134
{
102-
ChangesResult changes = client.changes(lastSeq);
135+
ChangesResult changes = getChangesSince(lastSeq);
103136
Assert.assertEquals(1, changes.size());
104137
lastSeq = changes.getLastSeq();
105138
}
@@ -109,7 +142,7 @@ public void changes_dbWithConflicts_changesMustSuccessfullyReturn() {
109142
Response res2 = ClientTestUtils.createHelloWorldDoc(client);
110143

111144
{
112-
ChangesResult changes = client.changes(lastSeq);
145+
ChangesResult changes = getChangesSince(lastSeq);
113146
Assert.assertEquals(2, changes.size());
114147

115148
List<String> doc1ChangedRevs = findChangesRevs(changes, res1.getId());
@@ -122,7 +155,7 @@ public void changes_dbWithConflicts_changesMustSuccessfullyReturn() {
122155
}
123156
}
124157

125-
public List<String> findChangesRevs(ChangesResult changes, String id) {
158+
private List<String> findChangesRevs(ChangesResult changes, String id) {
126159
List<String> changedRevs = new ArrayList<String>();
127160
for(ChangesResult.Row row : changes.getResults()) {
128161
if(row.getId().equals(id)) {
@@ -133,4 +166,8 @@ public List<String> findChangesRevs(ChangesResult changes, String id) {
133166
}
134167
return changedRevs;
135168
}
169+
170+
private ChangesResult getChangesSince(Object since) {
171+
return client.changes(since, null);
172+
}
136173
}

cloudant-sync-datastore-core/src/test/java/com/cloudant/sync/internal/mazha/ClientTestUtils.java

+11
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@
3131
import org.apache.commons.io.IOUtils;
3232
import org.junit.Assert;
3333

34+
import java.io.BufferedReader;
35+
import java.io.IOException;
3436
import java.io.InputStream;
3537
import java.io.InputStreamReader;
38+
import java.net.HttpURLConnection;
3639
import java.net.URI;
40+
import java.net.URISyntaxException;
3741
import java.util.ArrayList;
3842
import java.util.HashMap;
3943
import java.util.List;
@@ -235,5 +239,12 @@ public static List<String> getRemoteRevisionIDs(URI uri, CouchConfig config) thr
235239
return revisions;
236240
}
237241

242+
public static boolean isCouchDBV2(URI uri) throws URISyntaxException, IOException {
243+
URI root = new URI(uri.getScheme() + "://" + uri.getAuthority());
244+
HttpConnection connection = Http.GET(root);
245+
String response = connection.execute().responseAsString();
246+
return response.contains("\"version\":\"2.");
247+
}
248+
238249

239250
}

0 commit comments

Comments
 (0)