Micro-Batching with
Virtual Threads

A lightweight Java 21 library for micro-batching requests to any backend. Built with virtual threads, smart batching, and comprehensive Micrometer metrics. Released under Apache License 2.0.

๐Ÿ”“ Open Source โš–๏ธ Apache 2.0 Java 21 Virtual Threads Smart Batching Micrometer
MicroBatcher.java
Backend backend = batch -> {
    // Your backend logic
    return new BatchResult<>(
        successes, failures
    );
};

BatcherConfig config = BatcherConfig
    .builder()
    .batchSize(10)
    .lingerTime(Duration.ofMillis(100))
    .build();

try (MicroBatcher batcher = 
     new MicroBatcher<>(backend, config)) {
    CompletableFuture> 
        future = batcher.submit("data");
}

Powerful Features

Everything you need for efficient micro-batching

โšก

Virtual Threads

Leverage Java 21's Project Loom for high concurrency. Backend code can be blocking - virtual threads make it efficient.

๐Ÿ“ฆ

Smart Batching

Triggers on batch size OR linger time (whichever comes first). Ensures optimal throughput and low latency.

๐Ÿ”’

Atomic Commits

Optional atomic commit mode where entire batch fails if any request fails. Perfect for transactional operations.

๐Ÿ”Œ

Generic Backend

Works with any backend via the simple Backend<T> interface. HTTP, database, queues - anything.

๐Ÿ“Š

Comprehensive Metrics

Micrometer metrics for queue depth, success/failure rates, latencies. Ready for Prometheus, Grafana, and more.

๐Ÿ”„

Auto-Replay

Intelligent replay of successful items when batches contain mixed results. Backend-driven or config-based decisions.

Code Examples

See how easy it is to get started

Basic Micro-Batching

import com.vajrapulse.vortex.*;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;

// 1. Create a backend implementation
Backend backend = batch -> {
    List> successes = new ArrayList<>();
    List> failures = new ArrayList<>();
    
    for (String item : batch) {
        // Process item (e.g., HTTP call, database query)
        successes.add(new SuccessEvent<>(item));
    }
    
    return new BatchResult<>(successes, failures);
};

// 2. Configure the batcher
BatcherConfig config = BatcherConfig.builder()
    .batchSize(10)                    // Batch size trigger
    .lingerTime(Duration.ofMillis(100)) // Time-based trigger
    .atomicCommit(false)               // Optional: all-or-nothing
    .maxConcurrency(10)                // Max concurrent batches
    .build();

// 3. Create and use the batcher
try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
    CompletableFuture> future = batcher.submit("request-data");
    BatchResult result = future.get();
    // Handle result...
}

Atomic Commit Mode

// Enable atomic commits - entire batch fails if any item fails
BatcherConfig config = BatcherConfig.builder()
    .batchSize(10)
    .lingerTime(Duration.ofMillis(100))
    .atomicCommit(true)  // All-or-nothing
    .build();

try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
    // If any item in the batch fails, all items receive failure
    CompletableFuture> future = batcher.submit("data");
    BatchResult result = future.get();
    
    if (result.hasFailures()) {
        // All items in this batch failed
    }
}

Auto-Replay Successes

// Backend that decides when to replay
Backend backend = new Backend() {
    @Override
    public BatchResult dispatch(List batch) throws Exception {
        // Your dispatch logic
        return new BatchResult<>(successes, failures);
    }
    
    @Override
    public boolean shouldReplaySuccesses(BatchResult result) {
        // Replay when there are both successes and failures
        return !result.getFailures().isEmpty() 
            && !result.getSuccesses().isEmpty();
    }
};

// Or use config-based replay
BatcherConfig config = BatcherConfig.builder()
    .batchSize(10)
    .autoReplaySuccesses(true)  // Global replay policy
    .build();

Accessing Metrics

try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
    // Access Micrometer registry
    MeterRegistry registry = batcher.getMeterRegistry();
    
    // Metrics are automatically exposed:
    // - vortex.requests.submitted
    // - vortex.batches.dispatched
    // - vortex.requests.succeeded
    // - vortex.requests.failed
    // - vortex.queue.depth (gauge)
    // - vortex.batch.dispatch.latency
    // - vortex.request.wait.latency
    
    // Export to Prometheus, Grafana, etc.
    // registry.getMeters().forEach(...);
}

Get Started

Add Vortex to your project in minutes

Gradle (Kotlin DSL)

dependencies {
    implementation("com.vajrapulse:vortex:0.0.1")
}

Gradle (Groovy DSL)

dependencies {
    implementation 'com.vajrapulse:vortex:0.0.1'
}

Maven

<dependency>
    <groupId>com.vajrapulse</groupId>
    <artifactId>vortex</artifactId>
    <version>0.0.1</version>
</dependency>

Requirements

  • Java 21 or higher
  • Gradle 9.2.0+ or Maven 3.6+

Why Vortex?

Built for the modern Java ecosystem

01

Simple Backend API

Write synchronous, blocking code. Virtual threads handle the efficiency. No need to manage CompletableFuture in your backend.

02

Non-blocking Client API

Clients get async results via CompletableFuture. Compose, chain, and handle results asynchronously.

03

Production Ready

Comprehensive test coverage, Micrometer integration, and battle-tested patterns. Ready for production workloads.

04

Lightweight

Minimal dependencies. Clean, simple API. Easy to understand and integrate into any project.

๐Ÿ”“

Open Source & Free

Vortex is completely open source and free to use. Released under the Apache License 2.0, you can use it in commercial and personal projects without restrictions.

โš–๏ธ

Apache License 2.0

Permissive open source license that allows you to:

  • โœ… Use commercially
  • โœ… Modify and distribute
  • โœ… Use in proprietary software
  • โœ… Patent use granted
Read Full License
๐Ÿ’ก

Contribute & Collaborate

Vortex is built by the community, for the community. Contributions are welcome!

  • โœ… Open source on GitHub
  • โœ… Community-driven development
  • โœ… Issue tracking and PRs welcome
  • โœ… Transparent development process
View on GitHub