3737import io .weaviate .client6 .v1 .api .collections .batch .Event .StreamHangup ;
3838import io .weaviate .client6 .v1 .api .collections .data .BatchReference ;
3939import io .weaviate .client6 .v1 .api .collections .data .InsertManyRequest ;
40+ import io .weaviate .client6 .v1 .internal .ObjectBuilder ;
4041import io .weaviate .client6 .v1 .internal .orm .CollectionDescriptor ;
4142
4243/**
5253 * @param <PropertiesT> the shape of properties for inserted objects.
5354 */
5455public final class BatchContext <PropertiesT > implements Closeable {
55- private final int DEFAULT_BATCH_SIZE = 1_000 ;
56- private final int DEFAULT_QUEUE_SIZE = 100 ;
57- private final int MAX_RECONNECT_RETRIES = 5 ;
56+ private final int maxReconnectRetries = 5 ;
5857
5958 private final CollectionDescriptor <PropertiesT > collectionDescriptor ;
6059 private final CollectionHandleDefaults collectionHandleDefaults ;
@@ -88,7 +87,7 @@ public final class BatchContext<PropertiesT> implements Closeable {
8887
8988 /**
9089 * Queue publishes insert tasks from the main thread to the "sender".
91- * It has a maximum capacity of {@link #DEFAULT_QUEUE_SIZE }.
90+ * It has a maximum capacity of {@link #queueSize }.
9291 *
9392 * Send {@link TaskHandle#POISON} to gracefully shutdown the "sender"
9493 * thread. The same queue may be re-used with a different "sender",
@@ -156,13 +155,27 @@ public final class BatchContext<PropertiesT> implements Closeable {
156155 StreamFactory <Message , Event > streamFactory ,
157156 int maxSizeBytes ,
158157 CollectionDescriptor <PropertiesT > collectionDescriptor ,
159- CollectionHandleDefaults collectionHandleDefaults ) {
158+ CollectionHandleDefaults collectionHandleDefaults ,
159+ int batchSize ,
160+ int queueSize ,
161+ int maxReconnectRetries ) {
160162 this .streamFactory = requireNonNull (streamFactory , "streamFactory is null" );
161163 this .collectionDescriptor = requireNonNull (collectionDescriptor , "collectionDescriptor is null" );
162164 this .collectionHandleDefaults = requireNonNull (collectionHandleDefaults , "collectionHandleDefaults is null" );
163165
164- this .queue = new ArrayBlockingQueue <>(DEFAULT_QUEUE_SIZE );
165- this .batch = new Batch (DEFAULT_BATCH_SIZE , maxSizeBytes );
166+ this .queue = new ArrayBlockingQueue <>(queueSize );
167+ this .batch = new Batch (batchSize , maxSizeBytes );
168+ }
169+
170+ private BatchContext (Builder <PropertiesT > builder ) {
171+ this (
172+ builder .streamFactory ,
173+ builder .maxSizeBytes ,
174+ builder .collectionDescriptor ,
175+ builder .collectionHandleDefaults ,
176+ builder .batchSize ,
177+ builder .queueSize ,
178+ builder .maxReconnectRetries );
166179 }
167180
168181 /** Add {@link WeaviateObject} to the batch. */
@@ -189,7 +202,6 @@ void start(State nextState) {
189202 workers = new CountDownLatch (2 );
190203
191204 messages = streamFactory .createStream (new Recv ());
192- System .out .println ("create stream" );
193205
194206 // Start the stream and await Started message.
195207 messages .onNext (Message .start (collectionHandleDefaults .consistencyLevel ()));
@@ -233,10 +245,15 @@ public TaskHandle retry(TaskHandle taskHandle) throws InterruptedException {
233245 */
234246 @ Override
235247 public void close () throws IOException {
248+ boolean closedBefore = closed ;
236249 closed = true ;
237250
238- try {
251+ if (! closedBefore ) {
239252 shutdown ();
253+ }
254+
255+ try {
256+ closing .get ();
240257 } catch (InterruptedException | ExecutionException e ) {
241258 if (e instanceof InterruptedException ||
242259 e .getCause () instanceof InterruptedException ) {
@@ -248,8 +265,8 @@ public void close() throws IOException {
248265 }
249266 }
250267
251- private void shutdown () throws InterruptedException , ExecutionException {
252- CompletableFuture < Void > gracefulShutdown = CompletableFuture .runAsync (() -> {
268+ private void shutdown () {
269+ CompletableFuture .runAsync (() -> {
253270 try {
254271 // Poison the queue -- this will signal "send" to drain the remaing
255272 // items in the batch and in the backlog and exit.
@@ -270,13 +287,7 @@ private void shutdown() throws InterruptedException, ExecutionException {
270287 } catch (Exception e ) {
271288 closing .completeExceptionally (e );
272289 }
273-
274290 }, shutdownExec );
275-
276- // Complete shutdown as soon as one of these futures are completed.
277- // - gracefulShutdown completes if we managed to shutdown normally.
278- // - closing may complete sooner if shutdownNow is called.
279- CompletableFuture .anyOf (closing , gracefulShutdown ).get ();
280291 }
281292
282293 private void shutdownNow (Exception ex ) {
@@ -333,6 +344,26 @@ void setState(State nextState) {
333344 }
334345 }
335346
347+ /** Returns true if the next batch can be sent. */
348+ boolean canSend () {
349+ lock .lock ();
350+ try {
351+ return state .canSend ();
352+ } finally {
353+ lock .unlock ();
354+ }
355+ }
356+
357+ /** Returns true if the next batch can be assembled from the queued items. */
358+ boolean canPrepareNext () {
359+ lock .lock ();
360+ try {
361+ return state .canPrepareNext ();
362+ } finally {
363+ lock .unlock ();
364+ }
365+ }
366+
336367 /**
337368 * onEvent delegates event handling to {@link #state}.
338369 *
@@ -458,7 +489,7 @@ private void flush() throws InterruptedException {
458489 private void awaitCanSend () throws InterruptedException {
459490 lock .lock ();
460491 try {
461- while (!state . canSend ()) {
492+ while (!canSend ()) {
462493 stateChanged .await ();
463494 }
464495 } finally {
@@ -478,7 +509,7 @@ private void awaitCanSend() throws InterruptedException {
478509 private void awaitCanPrepareNext () throws InterruptedException {
479510 lock .lock ();
480511 try {
481- while (!state . canPrepareNext ()) {
512+ while (!canPrepareNext ()) {
482513 stateChanged .await ();
483514 }
484515 } finally {
@@ -649,7 +680,7 @@ private final void onStreamClosed(Event event) {
649680 hangup .exception ().printStackTrace ();
650681 }
651682 if (!send .isDone ()) {
652- setState (new Reconnecting (MAX_RECONNECT_RETRIES ));
683+ setState (new Reconnecting (maxReconnectRetries ));
653684 }
654685 }
655686
@@ -870,4 +901,46 @@ void scheduleReconnect(int reconnectIntervalSeconds) {
870901 }
871902 }, reconnectIntervalSeconds , reconnectIntervalSeconds , TimeUnit .SECONDS );
872903 }
904+
905+ public static class Builder <PropertiesT > implements ObjectBuilder <BatchContext <PropertiesT >> {
906+ private final StreamFactory <Message , Event > streamFactory ;
907+ private final int maxSizeBytes ;
908+ private final CollectionDescriptor <PropertiesT > collectionDescriptor ;
909+ private final CollectionHandleDefaults collectionHandleDefaults ;
910+
911+ Builder (
912+ StreamFactory <Message , Event > streamFactory ,
913+ int maxSizeBytes ,
914+ CollectionDescriptor <PropertiesT > collectionDescriptor ,
915+ CollectionHandleDefaults collectionHandleDefaults ) {
916+ this .streamFactory = streamFactory ;
917+ this .maxSizeBytes = maxSizeBytes ;
918+ this .collectionDescriptor = collectionDescriptor ;
919+ this .collectionHandleDefaults = collectionHandleDefaults ;
920+ }
921+
922+ private int batchSize = 1_000 ;
923+ private int queueSize = 1_000 ;
924+ private int maxReconnectRetries = 5 ;
925+
926+ public Builder <PropertiesT > batchSize (int batchSize ) {
927+ this .batchSize = batchSize ;
928+ return this ;
929+ }
930+
931+ public Builder <PropertiesT > queueSize (int queueSize ) {
932+ this .queueSize = queueSize ;
933+ return this ;
934+ }
935+
936+ public Builder <PropertiesT > maxReconnectRetries (int maxReconnectRetries ) {
937+ this .maxReconnectRetries = maxReconnectRetries ;
938+ return this ;
939+ }
940+
941+ @ Override
942+ public BatchContext <PropertiesT > build () {
943+ return new BatchContext <>(this );
944+ }
945+ }
873946}
0 commit comments