googleapis / googleapis/google-cloud-java

[java-firestore] runTransaction runs callback on very limited gRPC thread

Open
#13,126 2 comments 0 reactions 1 assignee Claimed by @dconeybe View on GitHub
api: firestore
Dominant language
Java
Stars
2.1k
Forks
1.2k
Avg merge
1d 23h
Merged PRs (30d)
154

Description

#### Steps to reproduce

1. Use provided example
2. Transactions-part of example is expected to complete in less than 7s, but in practice completes in ~40s.

#### Code example

```java
Firestore firestore = FirestoreOptions.getDefaultInstance().getService();

final List documents = new ArrayList<>();
final List> writeResults = new ArrayList<>();
for (int i=0; i < 64; i++) {
final DocumentReference docRef = firestore.collection("counters").document(""+i);
writeResults.add(docRef.set(Map.of("value", 0)));
documents.add(docRef);
}
for (var writeResult : writeResults) {
writeResult.get();
}

System.err.println("Starting update-transactions");
var transactionsStart = Instant.now();

// Using these specific options, it seems to work
// var runner = Executors.newCachedThreadPool();
// var options = TransactionOptions.createReadWriteOptionsBuilder().setExecutor(runner).build();

final List> transactions = new ArrayList<>();
for (var docRef : documents) {
transactions.add(firestore.runTransaction(transaction -> {
// Just simulate something blocking
Thread.sleep(5000);
transaction.update(docRef, "value", 1);
return null;
}));
}

for (var transactionFuture : transactions) {
transactionFuture.get();
}

var elapsed = Duration.between(transactionsStart, Instant.now());
System.err.println("Done updating in "+elapsed);
```

#### External references such as API reference guides

https://cloud.google.com/firestore/docs/samples/firestore-transaction-document-update#firestore_transaction_document_update-java

#### Any additional information below

Breaking inside the transaction-handler, it seems to be called on the a "grpc-transport-X" thread. I would assume the intention, judging by [TransactionRunner](https://github.com/googleapis/java-firestore/blob/9c42c70062dc16493ad1361cff4e04ce117a3d14/google-cloud-firestore/src/main/java/com/google/cloud/firestore/TransactionRunner.java#L87) is to use the default executor from the service-instance. This seems to be a `java.util.concurrent.ScheduledThreadPoolExecutor`, configured with a `maximumPoolSize` of 2147483647, but in practice somehow limited to 8, probably being the cause of the problem.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.