Skip to content

Commit ef0a1b6

Browse files
author
Hideki Itakura
committed
By extending Future, Future is allowed to remove itself from pendingFutures queue.
Problem: - pendingFutures keeps the references of RemoteRequestRetry which is extended from Future. Each RemoteRequestRetry size after downloaded document is around 1MB. By storing 100 RemoteRequestRetry instances into pendingFutures causes out-of-memory problem.
1 parent 2d44ac3 commit ef0a1b6

4 files changed

Lines changed: 41 additions & 7 deletions

File tree

src/main/java/com/couchbase/lite/replicator/PullerInternal.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.couchbase.lite.storage.SQLException;
1212
import com.couchbase.lite.support.BatchProcessor;
1313
import com.couchbase.lite.support.Batcher;
14+
import com.couchbase.lite.support.CustomFuture;
1415
import com.couchbase.lite.support.HttpClientFactory;
1516
import com.couchbase.lite.support.RemoteRequestCompletionBlock;
1617
import com.couchbase.lite.support.SequenceMap;
@@ -609,7 +610,7 @@ public void pullRemoteRevision(final RevisionInternal rev) {
609610
//create a final version of this variable for the log statement inside
610611
//FIXME find a way to avoid this
611612
final String pathInside = path.toString();
612-
Future future = sendAsyncMultipartDownloaderRequest("GET", pathInside, null, db, new RemoteRequestCompletionBlock() {
613+
CustomFuture future = sendAsyncMultipartDownloaderRequest("GET", pathInside, null, db, new RemoteRequestCompletionBlock() {
613614

614615
@Override
615616
public void onCompletion(HttpResponse httpResponse, Object result, Throwable e) {
@@ -632,10 +633,12 @@ public void onCompletion(HttpResponse httpResponse, Object result, Throwable e)
632633

633634
// Note that we've finished this task:
634635
--httpConnectionCount;
636+
635637
// Start another task if there are still revisions waiting to be pulled:
636638
pullRemoteRevisions();
637639
}
638640
});
641+
future.setQueue(pendingFutures);
639642
pendingFutures.add(future);
640643
}
641644

src/main/java/com/couchbase/lite/replicator/ReplicationInternal.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.couchbase.lite.support.BatchProcessor;
1212
import com.couchbase.lite.support.Batcher;
1313
import com.couchbase.lite.support.BlockingQueueListener;
14+
import com.couchbase.lite.support.CustomFuture;
1415
import com.couchbase.lite.support.CustomLinkedBlockingQueue;
1516
import com.couchbase.lite.support.HttpClientFactory;
1617
import com.couchbase.lite.support.RemoteRequestCompletionBlock;
@@ -596,7 +597,7 @@ public Future sendAsyncMultipartRequest(String method, String relativePath, Mult
596597
* @exclude
597598
*/
598599
@InterfaceAudience.Private
599-
public Future sendAsyncMultipartDownloaderRequest(String method, String relativePath, Object body, Database db, RemoteRequestCompletionBlock onCompletion) {
600+
public CustomFuture sendAsyncMultipartDownloaderRequest(String method, String relativePath, Object body, Database db, RemoteRequestCompletionBlock onCompletion) {
600601
try {
601602

602603
String urlStr = buildRelativeURLString(relativePath);
@@ -617,7 +618,7 @@ public Future sendAsyncMultipartDownloaderRequest(String method, String relative
617618

618619
request.setAuthenticator(getAuthenticator());
619620

620-
Future future = request.submit();
621+
CustomFuture future = request.submit();
621622
return future;
622623
} catch (MalformedURLException e) {
623624
Log.e(Log.TAG_SYNC, "Malformed URL for async request", e);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.couchbase.lite.support;
2+
3+
import java.util.Queue;
4+
import java.util.concurrent.Future;
5+
6+
/**
7+
* Created by hideki on 5/21/15.
8+
*/
9+
public interface CustomFuture<V> extends Future<V> {
10+
void setQueue(Queue queue);
11+
}

src/main/java/com/couchbase/lite/support/RemoteRequestRetry.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.IOException;
1313
import java.net.URL;
1414
import java.util.Map;
15+
import java.util.Queue;
1516
import java.util.concurrent.BlockingQueue;
1617
import java.util.concurrent.ExecutionException;
1718
import java.util.concurrent.ExecutorService;
@@ -31,7 +32,7 @@
3132
* in between the retries.
3233
*
3334
*/
34-
public class RemoteRequestRetry<T> implements Future<T> {
35+
public class RemoteRequestRetry<T> implements CustomFuture<T> {
3536

3637
public static int MAX_RETRIES = 3; // total number of attempts = 4 (1 initial + MAX_RETRIES)
3738
public static int RETRY_DELAY_MS = 4 * 1000; // 4 sec
@@ -64,9 +65,18 @@ public class RemoteRequestRetry<T> implements Future<T> {
6465

6566
private RemoteRequestType requestType;
6667

68+
6769
// for Retry task
6870
ScheduledFuture retryFuture = null;
6971

72+
private Queue queue = null;
73+
74+
@Override
75+
public void setQueue(Queue queue) {
76+
this.queue = queue;
77+
}
78+
79+
7080
/**
7181
* The kind of RemoteRequest that will be created on each retry attempt
7282
*/
@@ -105,14 +115,14 @@ public RemoteRequestRetry(RemoteRequestType requestType,
105115

106116
}
107117

108-
public Future submit() {
118+
public CustomFuture submit() {
109119
return submit(false);
110120
}
111121

112122
/**
113123
* @param gzip true - send gzipped request
114124
*/
115-
public Future submit(boolean gzip) {
125+
public CustomFuture submit(boolean gzip) {
116126

117127
RemoteRequest request = generateRemoteRequest();
118128

@@ -185,6 +195,13 @@ private RemoteRequest generateRemoteRequest() {
185195
return request;
186196
}
187197

198+
void removeFromQueue() {
199+
if (queue != null) {
200+
queue.remove(this);
201+
setQueue(null);
202+
}
203+
}
204+
188205
RemoteRequestCompletionBlock onCompletionInner = new RemoteRequestCompletionBlock() {
189206

190207
private void completed(HttpResponse httpResponse, Object result, Throwable e) {
@@ -194,11 +211,13 @@ private void completed(HttpResponse httpResponse, Object result, Throwable e) {
194211
completedSuccessfully.set(true);
195212

196213
onCompletionCaller.onCompletion(requestHttpResponse, requestResult, requestThrowable);
197-
214+
198215
// release unnecessary references to reduce memory usage as soon as called onComplete().
199216
requestHttpResponse = null;
200217
requestResult = null;
201218
requestThrowable = null;
219+
220+
removeFromQueue();
202221
}
203222

204223
@Override

0 commit comments

Comments
 (0)