Skip to content

Commit 539bd8b

Browse files
committed
Merge pull request #638 from couchbase/feature/issue_635_jackson_deserialization_exception
Fixed #635 - Jackson deserialization exception
2 parents c77fc15 + 00ec726 commit 539bd8b

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

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

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.couchbase.lite.util.URIUtils;
99
import com.couchbase.lite.util.Utils;
1010
import com.fasterxml.jackson.core.JsonFactory;
11+
import com.fasterxml.jackson.core.JsonParseException;
1112
import com.fasterxml.jackson.core.JsonParser;
1213
import com.fasterxml.jackson.core.JsonToken;
1314

@@ -74,6 +75,7 @@ public class ChangeTracker implements Runnable {
7475
private boolean running = false;
7576
private HttpUriRequest request;
7677
protected ChangeTrackerBackoff backoff;
78+
private long startTime = 0;
7779

7880

7981
public enum ChangeTrackerMode {
@@ -252,6 +254,8 @@ protected void runLoop() {
252254

253255
while (running) {
254256

257+
startTime = System.currentTimeMillis();
258+
255259
URL url = getChangesFeedURL();
256260
if (usePOST) {
257261
HttpPost postRequest = new HttpPost(url.toString());
@@ -340,26 +344,40 @@ public void process(HttpRequest request, HttpContext context) throws HttpExcepti
340344
// NOTE: 2. HttpEntity.getContentLength() returns the number of bytes of the content, or a negative number if unknown.
341345
boolean responseOK = false; // default value
342346
if (entity.getContentLength() != 0) {
343-
Log.v(Log.TAG_CHANGE_TRACKER, "%s: readValue", this);
344-
Map<String, Object> fullBody = Manager.getObjectMapper().readValue(inputStream, Map.class);
345-
Log.v(Log.TAG_CHANGE_TRACKER, "%s: /readValue. fullBody: %s", this, fullBody);
346-
responseOK = receivedPollResponse(fullBody);
347+
try {
348+
Log.v(Log.TAG_CHANGE_TRACKER, "%s: readValue", this);
349+
Map<String, Object> fullBody = Manager.getObjectMapper().readValue(inputStream, Map.class);
350+
Log.v(Log.TAG_CHANGE_TRACKER, "%s: /readValue. fullBody: %s", this, fullBody);
351+
responseOK = receivedPollResponse(fullBody);
352+
} catch (JsonParseException jpe) {
353+
Log.w(Log.TAG_CHANGE_TRACKER, "%s: json parsing error; %s", this, jpe.toString());
354+
}
347355
}
348356
Log.v(Log.TAG_CHANGE_TRACKER, "%s: responseOK: %s", this, responseOK);
349357

350-
if (mode == ChangeTrackerMode.LongPoll && responseOK) {
351-
358+
if (responseOK) {
352359
// TODO: this logic is questionable, there's lots
353360
// TODO: of differences in the iOS changetracker code,
354361
client.changeTrackerCaughtUp();
355-
356362
Log.v(Log.TAG_CHANGE_TRACKER, "%s: Starting new longpoll", this);
357363
backoff.resetBackoff();
358364
continue;
359365
} else {
360-
Log.d(Log.TAG_CHANGE_TRACKER, "%s: Change tracker calling stop (LongPoll)", this);
361-
client.changeTrackerFinished(this);
362-
break;
366+
long elapsed = (System.currentTimeMillis() - startTime) / 1000;
367+
Log.w(Log.TAG_CHANGE_TRACKER, "%s: Longpoll connection closed (by proxy?) after %.1f sec", this, elapsed);
368+
if (elapsed >= 30) {
369+
// Looks like the connection got closed by a proxy (like AWS' load balancer) while the
370+
// server was waiting for a change to send, due to lack of activity.
371+
// Lower the heartbeat time to work around this, and reconnect:
372+
this.heartBeatSeconds = Math.min(this.heartBeatSeconds, (int) (elapsed * 0.75));
373+
Log.v(Log.TAG_CHANGE_TRACKER, "%s: Starting new longpoll", this);
374+
backoff.resetBackoff();
375+
continue;
376+
} else {
377+
Log.d(Log.TAG_CHANGE_TRACKER, "%s: Change tracker calling stop (LongPoll)", this);
378+
client.changeTrackerFinished(this);
379+
break;
380+
}
363381
}
364382
} else { // one-shot replications
365383

@@ -379,7 +397,6 @@ public void process(HttpRequest request, HttpContext context) throws HttpExcepti
379397

380398
if (jp != null) {
381399
jp.close();
382-
jp = null;
383400
}
384401

385402
Log.v(Log.TAG_CHANGE_TRACKER, "%s: /readValue (oneshot)", this);
@@ -403,14 +420,12 @@ public void process(HttpRequest request, HttpContext context) throws HttpExcepti
403420
}
404421
} catch (IOException e) {
405422
}
406-
inputStream = null;
407423
if (entity != null) {
408424
try {
409425
entity.consumeContent();
410426
} catch (IOException e) {
411427
}
412428
}
413-
entity = null;
414429
}
415430
}
416431
} catch (Exception e) {

0 commit comments

Comments
 (0)