New in 0.16.2

v0.16.3

Service

Batched Tasks

Purpose

A batched task is a specialized mode of execution of tasks that processes multiple tasks together in a single execution.

Here are some common use cases:

  1. Database Operations: When dealing with multiple database inserts, updates, or deletes, batch operations can reduce the number of database connections and transactions.

    Example:

  2. API Cost Optimization: When interacting with external APIs that charge per request, gathering multiple operations into a single API call can significantly reduce costs while maintaining functionality.

    Example:

  3. Resource-Intensive Computations: For tasks that require significant CPU or memory resources, batched tasks can optimize resource utilization.

    Example:

  4. Aggregated Reporting: When generating reports that involve data from multiple sources or require complex calculations, batch tasks can improve overall performance.

    Example:

Implementation

To enable batch tasks, you need to define a new dedicated method in your service implementation. Here's how to do it:

  1. Create a new method with the same name as the original task method.
  2. Annotate this new method with @Batch
  3. The method should take a Map<String, I> as a parameter, where I is the input type of the original task.
  4. The method should return a Map<String, O>, where O is the output type of the original task.
  5. The keys in both maps are task IDs, which Infinitic uses to correctly associate inputs with their corresponding outputs.
  6. When deploying your Service Executor, make sure to add a batch setting in your configuration.

This approach allows Infinitic to automatically aggregate multiple task invocations into a single execution.

For example:

If the original method has multiple parameters, the batch method should have a single parameter of type Map<String, I>. Here, I is a wrapper object that encapsulates all the parameters of the original method. This wrapper object should have a public constructor with the same parameters as the original method, in the same order.

In some cases, a batch method may not need to produce any output. For such scenarios:

  • The method can be declared with a void return type (Unit in Kotlin).
  • No explicit mapping of results to tasks is required.
  • Infinitic will treat the return value of each individual task as null.

Behavior

The batch process occurs after message deserialization. If a message corresponds to a method with a batch version, the message is added to the current aggregate for that method. An aggregate is processed when it reaches maxMessages or when maxSeconds have elapsed since the first message was added to it. The aggregate is then sent to the executor. With an executor concurrency of 10, up to 10 aggregates could potentially be executed in parallel.

Messages in an aggregate are only acknowledged after being succesfuly processed. If processing fails, all messages in the aggregate are considered failed and will be retried individually based on the retry strategy of the corresponding task.

Pulsar brokers have a parameter maxUnackedMessagesPerConsumer defaulting to 50,000. Ensure this number is consistent with your batch and concurrency settings.

If needed, consider also increasing the default value of 1,000 for the receiverQueue parameter of a client. This parameter determines how many messages can be loaded directly from the broker to the client.

Optional batch Key

By default, batch tasks are performed on a per-method basis. However, Infinitic provides the flexibility to create more specific batchs using a batch key. This feature allows you to group related tasks together.

To use a batch key, add a String value to the "batchKey" metadata when dispatching a task. Every batch aggregatewill then contain only tasks with the same batch key value.

Here are several examples of scenarios where batch keys can be particularly useful:

  1. Multi-tenancy: In a multi-tenant application, you might want to aggregate operations for each tenant separately. By using the tenant ID as the batch key, you ensure that operations for different tenants don't mix in the same aggregate.

  2. Geographic Distribution: For applications serving different regions, you can use the region or country code as the batch key to group related operations.

  3. Data Partitioning: When dealing with large datasets, you might partition your data based on certain criteria. Use the partition key as the batch key to ensure operations on the same partition are aggregated together.

batch Task Context

For convenience, a batchKey String property - initialized from the service metadata - has been added to the task context.

When processing tasks in batch, you can access the specific context of a task through:

Previous
Task Context