Skip to content

Commit 27ff9f6

Browse files
author
Brian Chen
authored
fix: add @BetaApi, make BulkWriter public, and refactor Executor (#497)
1 parent f78720a commit 27ff9f6

File tree

6 files changed

+57
-19
lines changed

6 files changed

+57
-19
lines changed

google-cloud-firestore/src/main/java/com/google/cloud/firestore/BulkWriter.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.api.core.ApiAsyncFunction;
2020
import com.google.api.core.ApiFuture;
2121
import com.google.api.core.ApiFutures;
22+
import com.google.api.core.BetaApi;
2223
import com.google.api.core.SettableApiFuture;
2324
import com.google.api.gax.rpc.StatusCode.Code;
2425
import com.google.cloud.firestore.v1.FirestoreSettings;
@@ -41,7 +42,9 @@
4142
import javax.annotation.Nonnull;
4243
import javax.annotation.Nullable;
4344

44-
final class BulkWriter implements AutoCloseable {
45+
/** A Firestore BulkWriter that can be used to perform a large number of writes in parallel. */
46+
@BetaApi
47+
public final class BulkWriter implements AutoCloseable {
4548
/**
4649
* A callback set by `addWriteResultListener()` to be run every time an operation successfully
4750
* completes.
@@ -182,15 +185,11 @@ public boolean onError(BulkWriterException error) {
182185
private final ScheduledExecutorService bulkWriterExecutor;
183186

184187
BulkWriter(FirestoreImpl firestore, BulkWriterOptions options) {
185-
this(firestore, options, Executors.newSingleThreadScheduledExecutor());
186-
}
187-
188-
BulkWriter(
189-
FirestoreImpl firestore,
190-
BulkWriterOptions options,
191-
ScheduledExecutorService bulkWriterExecutor) {
192188
this.firestore = firestore;
193-
this.bulkWriterExecutor = bulkWriterExecutor;
189+
this.bulkWriterExecutor =
190+
options.getExecutor() != null
191+
? options.getExecutor()
192+
: Executors.newSingleThreadScheduledExecutor();
194193
this.successExecutor = MoreExecutors.directExecutor();
195194
this.errorExecutor = MoreExecutors.directExecutor();
196195

google-cloud-firestore/src/main/java/com/google/cloud/firestore/BulkWriterException.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
package com.google.cloud.firestore;
1818

19+
import com.google.api.core.BetaApi;
1920
import com.google.cloud.firestore.BulkWriter.OperationType;
2021
import io.grpc.Status;
2122

2223
/** The error thrown when a BulkWriter operation fails. */
23-
final class BulkWriterException extends FirestoreException {
24+
@BetaApi
25+
public final class BulkWriterException extends FirestoreException {
2426
private final Status status;
2527
private final String message;
2628
private final DocumentReference documentReference;

google-cloud-firestore/src/main/java/com/google/cloud/firestore/BulkWriterOptions.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package com.google.cloud.firestore;
1818

19+
import com.google.api.core.BetaApi;
1920
import com.google.auto.value.AutoValue;
21+
import java.util.concurrent.ScheduledExecutorService;
2022
import javax.annotation.Nullable;
2123

2224
/** Options used to configure request throttling in BulkWriter. */
25+
@BetaApi
2326
@AutoValue
2427
abstract class BulkWriterOptions {
2528
/**
@@ -48,11 +51,19 @@ abstract class BulkWriterOptions {
4851
@Nullable
4952
abstract Double getMaxOpsPerSecond();
5053

54+
/**
55+
* @return The {@link ScheduledExecutorService} that BulkWriter uses to schedule all operations.
56+
* If null, the default executor will be used.
57+
*/
58+
@Nullable
59+
abstract ScheduledExecutorService getExecutor();
60+
5161
static Builder builder() {
5262
return new AutoValue_BulkWriterOptions.Builder()
5363
.setMaxOpsPerSecond(null)
5464
.setInitialOpsPerSecond(null)
55-
.setThrottlingEnabled(true);
65+
.setThrottlingEnabled(true)
66+
.setExecutor(null);
5667
}
5768

5869
abstract Builder toBuilder();
@@ -104,6 +115,13 @@ Builder setMaxOpsPerSecond(int maxOpsPerSecond) {
104115
return setMaxOpsPerSecond(new Double(maxOpsPerSecond));
105116
}
106117

118+
/**
119+
* Set the executor that the BulkWriter instance schedules operations on.
120+
*
121+
* @param executor The executor to schedule BulkWriter operations on.
122+
*/
123+
abstract Builder setExecutor(@Nullable ScheduledExecutorService executor);
124+
107125
abstract BulkWriterOptions autoBuild();
108126

109127
BulkWriterOptions build() {

google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.firestore;
1818

1919
import com.google.api.core.ApiFuture;
20+
import com.google.api.core.BetaApi;
2021
import com.google.api.core.InternalExtensionOnly;
2122
import com.google.api.gax.rpc.ApiStreamObserver;
2223
import com.google.cloud.Service;
@@ -168,9 +169,30 @@ void getAll(
168169
@Nonnull
169170
WriteBatch batch();
170171

172+
/**
173+
* Creates a {@link BulkWriter} instance, used for performing multiple writes in parallel.
174+
* Gradually ramps up writes as specified by the 500/50/5 rule.
175+
*
176+
* @see <a href=https://cloud.google.com/datastore/docs/best-practices#ramping_up_traffic>Ramping
177+
* up traffic</a>
178+
*/
179+
@BetaApi
171180
@Nonnull
172181
BulkWriter bulkWriter();
173182

183+
/**
184+
* Creates a {@link BulkWriter} instance, used for performing multiple writes in parallel.
185+
* Gradually ramps up writes as specified by the 500/50/5 rule unless otherwise configured by a
186+
* BulkWriterOptions object.
187+
*
188+
* @see <a href=https://cloud.google.com/datastore/docs/best-practices#ramping_up_traffic>Ramping
189+
* up traffic</a>
190+
* @param options An options object to configure BulkWriter.
191+
*/
192+
@BetaApi
193+
@Nonnull
194+
BulkWriter bulkWriter(BulkWriterOptions options);
195+
174196
/**
175197
* Returns a FirestoreBundle.Builder {@link FirestoreBundle.Builder} instance using an
176198
* automatically generated bundle ID. When loaded on clients, client SDKs use the bundle ID and

google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.List;
4040
import java.util.Map;
4141
import java.util.Random;
42-
import java.util.concurrent.ScheduledExecutorService;
4342
import javax.annotation.Nonnull;
4443
import javax.annotation.Nullable;
4544

@@ -99,15 +98,10 @@ public BulkWriter bulkWriter() {
9998
}
10099

101100
@Nonnull
102-
BulkWriter bulkWriter(BulkWriterOptions options) {
101+
public BulkWriter bulkWriter(BulkWriterOptions options) {
103102
return new BulkWriter(this, options);
104103
}
105104

106-
@Nonnull
107-
BulkWriter bulkWriter(BulkWriterOptions options, ScheduledExecutorService executor) {
108-
return new BulkWriter(this, options, executor);
109-
}
110-
111105
@Nonnull
112106
@Override
113107
public CollectionReference collection(@Nonnull String collectionPath) {

google-cloud-firestore/src/test/java/com/google/cloud/firestore/BulkWriterTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,10 @@ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
953953
responseStubber.initializeStub(batchWriteCapture, firestoreMock);
954954
BulkWriter bulkWriter =
955955
firestoreMock.bulkWriter(
956-
BulkWriterOptions.builder().setInitialOpsPerSecond(5).build(), timeoutExecutor);
956+
BulkWriterOptions.builder()
957+
.setInitialOpsPerSecond(5)
958+
.setExecutor(timeoutExecutor)
959+
.build());
957960

958961
for (int i = 0; i < 600; ++i) {
959962
bulkWriter.set(firestoreMock.document("coll/doc"), LocalFirestoreHelper.SINGLE_FIELD_MAP);

0 commit comments

Comments
 (0)