Skip to content

Commit 11712fd

Browse files
committed
Merge pull request #1032 from couchbase/feature/issue_1030_listener_hange_state
Fixed #1030 - Requests to Listener in pending state
2 parents c605cb7 + 36f1ab6 commit 11712fd

2 files changed

Lines changed: 39 additions & 18 deletions

File tree

src/main/java/com/couchbase/lite/Manager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public final class Manager {
6969
public static final String SQLITE_STORAGE = "SQLite";
7070
public static final String FORESTDB_STORAGE = "ForestDB";
7171

72+
// NOTE: Jackson is thread-safe http://wiki.fasterxml.com/JacksonFAQThreadSafety
7273
private static final ObjectMapper mapper = new ObjectMapper();
7374

7475
private ManagerOptions options;

src/main/java/com/couchbase/lite/router/Router.java

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ public void start() {
365365
return;
366366
} else {
367367
boolean mustExist = false;
368-
db = manager.getDatabase(dbName, mustExist);
368+
db = manager.getDatabase(dbName, mustExist); // NOTE: synchronized
369369
if (db == null) {
370370
connection.setResponseCode(Status.BAD_REQUEST);
371371
try {
@@ -548,10 +548,9 @@ public void start() {
548548
waiting = true;
549549
}
550550

551-
if (waiting) {
552-
if (db != null) {
553-
db.addDatabaseListener(this);
554-
}
551+
if (waiting && db != null) {
552+
Log.v(Log.TAG_ROUTER, "waiting=true & db!=null: call Database.addDatabaseListener()");
553+
db.addDatabaseListener(this);
555554
}
556555
}
557556

@@ -692,6 +691,7 @@ public Status do_POST_replicate(Database _db, String _docID, String _attachmentN
692691
}
693692

694693
try {
694+
// NOTE: replicator instance is created per request. not access shared instances
695695
replicator = manager.getReplicator(body);
696696
} catch (CouchbaseLiteException e) {
697697
Map<String, Object> result = new HashMap<String, Object>();
@@ -978,6 +978,7 @@ public Status do_GET_Database(Database _db, String _docID, String _attachmentNam
978978
if (!status.isSuccessful()) {
979979
return status;
980980
}
981+
// NOTE: all methods are read operation. not necessary to be synchronized
981982
int num_docs = db.getDocumentCount();
982983
long update_seq = db.getLastSequenceNumber();
983984
long instanceStartTimeMicroseconds = db.getStartTime() * 1000;
@@ -999,6 +1000,7 @@ public Status do_PUT_Database(Database _db, String _docID, String _attachmentNam
9991000
}
10001001

10011002
try {
1003+
// note: synchronized
10021004
db.open();
10031005
} catch (CouchbaseLiteException e) {
10041006
return e.getCBLStatus();
@@ -1012,7 +1014,9 @@ public Status do_DELETE_Database(Database _db, String _docID, String _attachment
10121014
if (getQuery("rev") != null) {
10131015
return new Status(Status.BAD_REQUEST); // CouchDB checks for this; probably meant to be a document deletion
10141016
}
1015-
db.delete();
1017+
synchronized (db) {
1018+
db.delete();
1019+
}
10161020
return new Status(Status.OK);
10171021
}
10181022

@@ -1883,10 +1887,12 @@ private RevisionInternal update(Database _db, String docID, Body body, boolean d
18831887

18841888
RevisionInternal result = null;
18851889
try {
1886-
if (isLocalDoc) {
1887-
result = _db.getStore().putLocalRevision(rev, prevRevID, true);
1888-
} else {
1889-
result = _db.putRevision(rev, prevRevID, allowConflict);
1890+
synchronized (_db) {
1891+
if (isLocalDoc) {
1892+
result = _db.getStore().putLocalRevision(rev, prevRevID, true);
1893+
} else {
1894+
result = _db.putRevision(rev, prevRevID, allowConflict);
1895+
}
18901896
}
18911897
if (deleting) {
18921898
outStatus.setCode(Status.OK);
@@ -1922,8 +1928,6 @@ private Status update(Database _db, String docID, Body body, boolean deleting) {
19221928
// On PUT/DELETE, get revision ID from either ?rev= query or doc body:
19231929
String revParam = getQuery("rev");
19241930

1925-
// TODO: If-Match
1926-
19271931
if (revParam != null && body != null) {
19281932
String revProp = (String) body.getProperties().get("_rev");
19291933
if (revProp == null) {
@@ -1989,7 +1993,10 @@ public Status do_DELETE_Document(Database _db, String docID, String _attachmentN
19891993
return update(_db, docID, null, true);
19901994
}
19911995

1992-
private Status updateAttachment(String attachment, String docID, InputStream contentStream) throws CouchbaseLiteException {
1996+
private Status updateAttachment(String attachment,
1997+
String docID,
1998+
InputStream contentStream)
1999+
throws CouchbaseLiteException {
19932000
Status status = new Status(Status.OK);
19942001
String revID = getQuery("rev");
19952002
if (revID == null) {
@@ -2007,8 +2014,17 @@ private Status updateAttachment(String attachment, String docID, InputStream con
20072014
throw new CouchbaseLiteException(e.getCause(), Status.BAD_ATTACHMENT);
20082015
}
20092016

2010-
RevisionInternal rev = db.updateAttachment(attachment, body, connection.getRequestProperty("content-type"), AttachmentInternal.AttachmentEncoding.AttachmentEncodingNone,
2011-
docID, revID, null);
2017+
RevisionInternal rev;
2018+
synchronized (db) {
2019+
rev = db.updateAttachment(
2020+
attachment,
2021+
body,
2022+
connection.getRequestProperty("content-type"),
2023+
AttachmentInternal.AttachmentEncoding.AttachmentEncodingNone,
2024+
docID,
2025+
revID,
2026+
null);
2027+
}
20122028
Map<String, Object> resultDict = new HashMap<String, Object>();
20132029
resultDict.put("ok", true);
20142030
resultDict.put("id", rev.getDocID());
@@ -2021,11 +2037,13 @@ private Status updateAttachment(String attachment, String docID, InputStream con
20212037
return status;
20222038
}
20232039

2024-
public Status do_PUT_Attachment(Database _db, String docID, String _attachmentName) throws CouchbaseLiteException {
2040+
public Status do_PUT_Attachment(Database _db, String docID, String _attachmentName)
2041+
throws CouchbaseLiteException {
20252042
return updateAttachment(_attachmentName, docID, connection.getRequestInputStream());
20262043
}
20272044

2028-
public Status do_DELETE_Attachment(Database _db, String docID, String _attachmentName) throws CouchbaseLiteException {
2045+
public Status do_DELETE_Attachment(Database _db, String docID, String _attachmentName)
2046+
throws CouchbaseLiteException {
20292047
return updateAttachment(_attachmentName, docID, null);
20302048
}
20312049

@@ -2101,7 +2119,9 @@ private Status queryDesignDoc(String designDoc, String viewName, List<Object> ke
21012119
options.setKeys(keys);
21022120
}
21032121

2104-
view.updateIndex();
2122+
synchronized (db) {
2123+
view.updateIndex();
2124+
}
21052125

21062126
long lastSequenceIndexed = view.getLastSequenceIndexed();
21072127

0 commit comments

Comments
 (0)