This is an automated email from the ASF dual-hosted git repository.
reschke pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new f165691e0b OAK-10650: MongoDocumentStore.findDocuments can fail with
BSON exception (#1307)
f165691e0b is described below
commit f165691e0bff0aa7ed5a2650a11dd52630181b20
Author: Julian Reschke <[email protected]>
AuthorDate: Wed Feb 14 15:49:03 2024 +0100
OAK-10650: MongoDocumentStore.findDocuments can fail with BSON exception
(#1307)
---
.../plugins/document/mongo/MongoDocumentStore.java | 52 +++++++++++++++++++---
1 file changed, 45 insertions(+), 7 deletions(-)
diff --git
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
index 1f156f4100..604829b38d 100644
---
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
+++
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
@@ -84,6 +84,7 @@ import
org.apache.jackrabbit.oak.plugins.document.locks.StripedNodeDocumentLocks
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.apache.jackrabbit.oak.stats.Clock;
import org.apache.jackrabbit.oak.commons.PerfLogger;
+import org.bson.BSONException;
import org.bson.BsonMaximumSizeExceededException;
import org.bson.conversions.Bson;
import org.jetbrains.annotations.NotNull;
@@ -1524,12 +1525,48 @@ public class MongoDocumentStore implements
DocumentStore {
}
private <T extends Document> Map<String, T> findDocuments(Collection<T>
collection, Set<String> keys) {
- Map<String, T> docs = new HashMap<String, T>();
- if (!keys.isEmpty()) {
- List<Bson> conditions = new ArrayList<>(keys.size());
- for (String key : keys) {
- conditions.add(getByKeyQuery(key));
+ try {
+ Map<String, T> docs = new HashMap<String, T>();
+ if (!keys.isEmpty()) {
+ List<Bson> conditions = new ArrayList<>(keys.size());
+ for (String key : keys) {
+ conditions.add(getByKeyQuery(key));
+ }
+ MongoCollection<BasicDBObject> dbCollection;
+ if (secondariesWithinAcceptableLag()) {
+ dbCollection = getDBCollection(collection);
+ } else {
+ lagTooHigh();
+ dbCollection =
getDBCollection(collection).withReadPreference(ReadPreference.primary());
+ }
+ execute(session -> {
+ FindIterable<BasicDBObject> cursor;
+ if (session != null) {
+ cursor = dbCollection.find(session,
Filters.or(conditions));
+ } else {
+ cursor = dbCollection.find(Filters.or(conditions));
+ }
+ for (BasicDBObject doc : cursor) {
+ T foundDoc = convertFromDBObject(collection, doc);
+ docs.put(foundDoc.getId(), foundDoc);
+ }
+ return null;
+ }, collection);
}
+ return docs;
+ } catch (BSONException ex) {
+ // TODO: refactor, see OAK-10650
+ LOG.error("trying bulk find, retrying one-by-one", ex);
+ return findDocumentsOneByOne(collection, keys);
+ }
+ }
+
+ // variant of findDocuments that avoids BSON exception by iterating
instead of doing a bulk operation
+ private <T extends Document> Map<String, T>
findDocumentsOneByOne(Collection<T> collection, Set<String> keys) {
+ Map<String, T> docs = new HashMap<String, T>();
+ for (String key : keys) {
+ Bson condition = getByKeyQuery(key);
+
MongoCollection<BasicDBObject> dbCollection;
if (secondariesWithinAcceptableLag()) {
dbCollection = getDBCollection(collection);
@@ -1540,9 +1577,9 @@ public class MongoDocumentStore implements DocumentStore {
execute(session -> {
FindIterable<BasicDBObject> cursor;
if (session != null) {
- cursor = dbCollection.find(session,
Filters.or(conditions));
+ cursor = dbCollection.find(session, condition);
} else {
- cursor = dbCollection.find(Filters.or(conditions));
+ cursor = dbCollection.find(condition);
}
for (BasicDBObject doc : cursor) {
T foundDoc = convertFromDBObject(collection, doc);
@@ -1551,6 +1588,7 @@ public class MongoDocumentStore implements DocumentStore {
return null;
}, collection);
}
+
return docs;
}