Skip to content

BatchBuilder ​

Builders for processing collections of items as coordinated batch jobs. Ratchet provides two batch builders:

  • BatchBuilder -- for in-memory collections where the total size is known up front.
  • StreamingBatchBuilder<T> -- for large datasets read from a Stream, processed in chunks without loading everything into memory.

Package: run.ratchet.api

BatchBuilder ​

Obtained from JobSchedulerService.enqueueBatch().

forEach ​

java
<T extends Serializable> BatchBuilder forEach(
    Collection<T> items, SerializableConsumer<T> action)

Applies an action to each item in the collection. Each item becomes a child job in the batch.

Type Parameters:

  • T -- the type of elements; must implement Serializable.

Parameters:

  • items -- the collection of items to process.
  • action -- the operation to perform on each item.

Returns: the BatchBuilder for chaining.

java
List<Long> orderIds = List.of(1L, 2L, 3L, 4L, 5L);

scheduler.enqueueBatch("Process Orders")
    .forEach(orderIds, orderId -> orderService.process(orderId))
    .withMaxRetries(3)
    .withBackoff(BackoffPolicy.EXPONENTIAL, Duration.ofSeconds(2))
    .submit();

withMaxRetries ​

java
BatchBuilder withMaxRetries(int retries)

Sets the number of retry attempts for every child job. The default is 0, so a child runs once unless retries are explicitly enabled. A negative value throws IllegalArgumentException.

The setting belongs to the whole builder and applies even when called after forEach. It does not apply to the no-op batch parent or workflow branches.

withBackoff ​

java
BatchBuilder withBackoff(BackoffPolicy policy, Duration param)

Sets the backoff policy and base delay used between child retry attempts. Both arguments are required. This does not enable retries by itself; set withMaxRetries to a positive value as well. The setting applies to the whole builder, regardless of call order.

java
scheduler.enqueueBatch("Process Orders")
    .forEach(orderIds, orderId -> orderService.process(orderId))
    .withMaxRetries(3)
    .withBackoff(BackoffPolicy.EXPONENTIAL, Duration.ofSeconds(2))
    .submit();

withTimeout ​

java
BatchBuilder withTimeout(Duration timeout)

Sets the execution timeout for every child job. Null is the default and clears the override, leaving children on the global default SLA. The setting applies to the whole builder, including children already added. It does not apply to the batch parent or to workflow branch and callback jobs.

Timeouts are stored in whole seconds. Negative durations, positive durations under one second, and values above Integer.MAX_VALUE whole seconds throw IllegalArgumentException.

java
scheduler.enqueueBatch("Process Orders")
    .forEach(orderIds, orderId -> orderService.process(orderId))
    .withTimeout(Duration.ofMinutes(45))
    .submit();

withCallbackOptions ​

java
BatchBuilder withCallbackOptions(JobOptions options)

Sets priority, retries, backoff and timeout for jobs created by thenOnBatchSuccess, thenOnBatchFailure, thenWhenSuccessRate, thenWhenFailureCount, thenWhenBatch and thenBranch.

The default is JobOptions.defaults(): NORMAL priority, no retries, no backoff and the global default SLA. Child settings from withMaxRetries, withBackoff and withTimeout do not apply to callbacks. The setting applies to the whole builder regardless of call order. Callbacks use these options for both retries and backoff.

java
batch.withCallbackOptions(JobOptions.defaults()
    .withMaxRetries(2)
    .withTimeout(Duration.ofHours(1))
    .withPriority(JobPriority.HIGH));

withResource ​

java
BatchBuilder withResource(String resourceName)

Every child acquires a permit from the named resource pool before it runs. At capacity, children are rescheduled without counting as retries. The configured permit count caps how many children run at once. That count is shared with all other jobs using the same resource name, inside or outside the batch.

The setting applies to every child regardless of call order. The no-op parent, progress hooks, and workflow branch jobs do not inherit it. Null or blank disables resource limiting. Other names are trimmed.

submit() throws UnsupportedOperationException if a resource is set and the store does not advertise the ResourcePermitStore capability. Streaming batches have the same behavior at start().

Configure permit counts and retry delays in scheduler_resource_limit, using max_concurrent and retry_delay_ms. See Performance Tuning.

java
scheduler.enqueueBatch("Payments")
    .forEach(paymentIds, id -> paymentService.charge(id))
    .withResource("payment-api")
    .submit();

onProgress ​

java
BatchBuilder onProgress(SerializableConsumer<BatchContext> hook)

Registers a progress hook invoked as child jobs complete. The hook receives a BatchContext snapshot with current progress metrics.

Parameters:

  • hook -- a consumer receiving BatchContext updates.

Returns: the BatchBuilder for chaining.

java
scheduler.enqueueBatch("Import Records")
    .forEach(records, record -> importService.importRecord(record))
    .onProgress(ctx -> {
        log.info("Batch {}: {}% complete ({}/{} items, {} failed)",
            ctx.batchId(), ctx.percentDone(),
            ctx.completedItems(), ctx.totalItems(), ctx.failedItems());
    })
    .submit();

thenOnBatchSuccess ​

java
BatchBuilder thenOnBatchSuccess(SerializableCheckedRunnable next)

Schedules a job to execute when all child jobs complete successfully (zero failures).

Parameters:

  • next -- the task to execute on batch success.
java
scheduler.enqueueBatch("Nightly Sync")
    .forEach(accounts, acct -> syncService.sync(acct))
    .thenOnBatchSuccess(() -> notificationService.sendSyncComplete())
    .submit();

thenOnBatchFailure ​

java
BatchBuilder thenOnBatchFailure(SerializableCheckedRunnable next)

Schedules a job to execute when one or more child jobs fail.

Parameters:

  • next -- the task to execute on batch failure.
java
scheduler.enqueueBatch("Data Migration")
    .forEach(rows, row -> migrationService.migrate(row))
    .thenOnBatchFailure(() -> alertService.migrationPartiallyFailed())
    .submit();

thenWhenBatch ​

java
BatchBuilder thenWhenBatch(
    SerializablePredicate<BatchContext> condition,
    SerializableCheckedRunnable next)

Schedules a job when a custom condition on the BatchContext is met.

Parameters:

  • condition -- predicate evaluating the BatchContext.
  • next -- the task to execute when the condition is true.
java
public final class BatchWorkflowConditions {
    public static boolean isCompleteWithoutFailures(BatchContext ctx) {
        return ctx.failedItems() == 0 && ctx.isComplete();
    }

    public static boolean shouldRollback(BatchContext ctx) {
        return ctx.failedItems() > ctx.totalItems() / 2;
    }
}

scheduler.enqueueBatch("Process Items")
    .forEach(items, item -> processItem(item))
    .thenWhenBatch(BatchWorkflowConditions::isCompleteWithoutFailures,
                   () -> archiveResults())
    .thenWhenBatch(BatchWorkflowConditions::shouldRollback,
                   () -> rollbackProcessing())
    .submit();

Custom batch predicates are analyzed into JobPayload JSON at submission time. Put compound logic in a public helper or CDI bean method, then pass a method reference.

thenWhenSuccessRate ​

java
BatchBuilder thenWhenSuccessRate(double minRate, SerializableCheckedRunnable next)

Schedules a job when the success rate meets or exceeds the specified threshold.

Parameters:

  • minRate -- minimum success rate (0.0 to 1.0).
  • next -- the task to execute when the success rate condition is met.
java
scheduler.enqueueBatch("Email Campaign")
    .forEach(recipients, r -> emailService.sendCampaign(r))
    .thenWhenSuccessRate(0.95, () -> log.info("Campaign delivered successfully"))
    .thenWhenSuccessRate(0.50, () -> alertService.campaignPartialFailure())
    .submit();

thenWhenFailureCount ​

java
BatchBuilder thenWhenFailureCount(int maxFailures, SerializableCheckedRunnable next)

Schedules a job when the number of failures stays at or below the specified threshold (failures less than or equal to maxFailures).

Parameters:

  • maxFailures -- the maximum number of failures (inclusive) for which the action still fires.
  • next -- the task to execute when the failure count is within the threshold.
java
scheduler.enqueueBatch("Import Data")
    .forEach(rows, row -> importRow(row))
    .thenWhenFailureCount(10, () -> alertService.importWithinFailureBudget())
    .submit();

thenBranch ​

java
BatchBuilder thenBranch(WorkflowCondition condition,
                        SerializableCheckedRunnable next,
                        String description)

Adds a workflow branch with an explicit WorkflowCondition and description.

Parameters:

  • condition -- the WorkflowCondition determining when this branch fires.
  • next -- the task to execute.
  • description -- human-readable description for monitoring.
java
public final class BatchWorkflowConditions {
    public static boolean hasMoreThanFiveFailures(BatchContext ctx) {
        return ctx.failedItems() > 5 && ctx.isComplete();
    }
}

scheduler.enqueueBatch("Complex Batch")
    .forEach(items, item -> processItem(item))
    .thenBranch(
        WorkflowCondition.batchCustom(BatchWorkflowConditions::hasMoreThanFiveFailures),
        () -> escalateToOps(),
        "Escalate when more than 5 items fail")
    .submit();

submit ​

java
JobHandle submit()

Submits the configured batch for execution.

Returns: a JobHandle for the batch parent job.

java
JobHandle handle = scheduler.enqueueBatch("My Batch")
    .forEach(items, item -> processItem(item))
    .submit();

log.info("Batch submitted with ID {}", handle.id());

StreamingBatchBuilder ​

Obtained from JobSchedulerService.streamingBatch(). Designed for large datasets where items are read from a Stream and inserted in configurable chunks.

Framework extensions that build invocations directly (rather than serializing lambdas) have mirrored builders — InvocationBatchBuilder and InvocationStreamingBatchBuilder<T> — on the InvocationSubmissionService SPI.

StreamingBatchBuilder exposes the same child retry, timeout, resource, and callback option methods as BatchBuilder:

java
StreamingBatchBuilder<T> withMaxRetries(int retries)
StreamingBatchBuilder<T> withBackoff(BackoffPolicy policy, Duration param)
StreamingBatchBuilder<T> withTimeout(Duration timeout)
StreamingBatchBuilder<T> withCallbackOptions(JobOptions options)
StreamingBatchBuilder<T> withResource(String resourceName)

The invocation-typed mirrors expose the same methods and persist the same child retry options and resource name.

fromStream ​

java
StreamingBatchBuilder<T> fromStream(Stream<T> stream)

Sets the input data source for the batch. The stream item type T is fixed when the builder is created via streamingBatch() and must implement Serializable.

Parameters:

  • stream -- the stream of items to process.
java
scheduler.<Long>streamingBatch("Process Users")
    .fromStream(userRepository.streamAllIds())
    // ...

process ​

java
StreamingBatchBuilder<T> process(SerializableCheckedConsumer<T> action)

Configures the processing logic applied to each item. The action can throw checked exceptions.

Parameters:

  • action -- the processing action for each item.
java
scheduler.<Long>streamingBatch("Migrate Users")
    .fromStream(userIds.stream())
    .process(userId -> migrationService.migrateUser(userId))
    // ...

withChunkSize ​

java
StreamingBatchBuilder<T> withChunkSize(int size)

Sets the number of items per database insert chunk. Default is 100. Tune this based on your database's bulk insert performance.

Parameters:

  • size -- items per chunk. Must be positive.
java
scheduler.<Record>streamingBatch("Bulk Import")
    .fromStream(records.stream())
    .process(record -> importRecord(record))
    .withChunkSize(2000)
    // ...

onProgress ​

java
StreamingBatchBuilder<T> onProgress(Consumer<StreamingBatchContext> hook)

Registers a progress hook called during the stream consumption phase (not during job execution). Receives a StreamingBatchContext with streaming progress.

Parameters:

  • hook -- a consumer receiving StreamingBatchContext updates.
java
scheduler.<Long>streamingBatch("Stream Import")
    .fromStream(dataStream)
    .process(item -> processItem(item))
    .onProgress(ctx -> log.info("Streamed {} items in {} chunks",
        ctx.processedItems(), ctx.chunksInserted()))
    // ...

onBatchProgress ​

java
StreamingBatchBuilder<T> onBatchProgress(SerializableConsumer<BatchContext> hook)

Registers a progress hook called during job execution (after streaming is complete). Receives a BatchContext with execution progress.

Parameters:

  • hook -- a consumer receiving BatchContext updates.
java
scheduler.<Long>streamingBatch("Process Stream")
    .fromStream(ids.stream())
    .process(id -> processId(id))
    .onBatchProgress(ctx -> log.info("Execution: {}% complete", ctx.percentDone()))
    // ...

Workflow methods ​

StreamingBatchBuilder supports the same workflow methods as BatchBuilder:

java
StreamingBatchBuilder<T> thenOnBatchSuccess(SerializableCheckedRunnable next)
StreamingBatchBuilder<T> thenOnBatchFailure(SerializableCheckedRunnable next)
StreamingBatchBuilder<T> thenWhenBatch(
    SerializablePredicate<BatchContext> condition, SerializableCheckedRunnable next)
StreamingBatchBuilder<T> thenWhenFailureCount(int maxFailures, SerializableCheckedRunnable next)
StreamingBatchBuilder<T> thenWhenSuccessRate(double minRate, SerializableCheckedRunnable next)

start ​

java
JobHandle start()

Starts the streaming batch operation. The stream is consumed, items are inserted in chunks, and child jobs are created.

Returns: a JobHandle for the batch parent job.

java
JobHandle handle = scheduler.<Long>streamingBatch("Full Migration")
    .fromStream(repository.streamAll())
    .process(id -> migrationService.migrate(id))
    .withChunkSize(1000)
    .withMaxRetries(3)
    .withBackoff(BackoffPolicy.EXPONENTIAL, Duration.ofSeconds(2))
    .onProgress(ctx -> log.info("Streamed {} items", ctx.processedItems()))
    .thenOnBatchSuccess(() -> log.info("Migration complete"))
    .thenOnBatchFailure(() -> alertService.migrationFailed())
    .start();

BatchBuilder vs StreamingBatchBuilder ​

AspectBatchBuilderStreamingBatchBuilder
InputCollection<T> (in memory)Stream<T> (lazy)
MemoryEntire collection loadedChunked, constant memory
Total known at startYesNo (stream not exhausted)
Progress during creationN/AStreamingBatchContext
Progress during executionBatchContextBatchContext
Best forSmall-medium collectionsLarge datasets, database cursors
Submit methodsubmit()start()

See also ​