Skip to content

Quickstart (Core Engine) ​

Get up and running with OxMQ in a Java 17+ / Java 21+ application in less than 5 minutes.


📋 Prerequisites ​

  • Java 17 or newer (OpenJDK, Temurin, Corretto, GraalVM) — automatic Project Loom Virtual Threads on Java 21+
  • Redis 6.2+, Redis 7.x, or Valkey running locally or in Docker
bash
# Start a clean Redis instance via Docker
docker run -d --name oxmq-redis -p 6379:6379 redis:7-alpine

📦 1. Add Dependency ​

xml
<dependencies>
    <dependency>
        <groupId>io.github.gaurav10610</groupId>
        <artifactId>oxmq-core</artifactId>
        <version>1.8.0</version>
    </dependency>
</dependencies>
kotlin
dependencies {
    implementation("io.github.gaurav10610:oxmq-core:1.8.0")
}
xml
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.github.gaurav10610.oxmq</groupId>
        <artifactId>oxmq-core</artifactId>
        <version>1.8.0</version>
    </dependency>
</dependencies>
kotlin
repositories {
    mavenCentral()
    maven { url = uri("https://jitpack.io") }
}

dependencies {
    implementation("com.github.gaurav10610.oxmq:oxmq-core:1.8.0")
}
xml
<!-- In your pom.xml -->
<repositories>
    <repository>
        <id>github</id>
        <url>https://maven.pkg.github.com/gaurav10610/oxmq</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>io.github.gaurav10610</groupId>
        <artifactId>oxmq-core</artifactId>
        <version>1.8.0</version>
    </dependency>
</dependencies>

<!-- Requires GitHub PAT with read:packages in ~/.m2/settings.xml -->
kotlin
repositories {
    mavenCentral()
    maven {
        url = uri("https://maven.pkg.github.com/gaurav10610/oxmq")
        credentials {
            username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
            password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
        }
    }
}

dependencies {
    implementation("io.github.gaurav10610:oxmq-core:1.8.0")
}

💡 Standalone JARs: You can also download pre-built binaries directly from GitHub Releases v1.8.0.


📝 2. Define Your Payload ​

OxMQ works natively with Java 17/21 records and standard POJOs via Jackson:

java
package com.example.model;

public record OrderInvoice(
    String orderId,
    String customerEmail,
    double amount
) {}

📤 3. Produce Jobs ​

Initialize a connection pool and enqueue jobs using OxmqQueue:

java
package com.example;

import com.example.model.OrderInvoice;
import io.oxmq.OxmqQueue;
import io.oxmq.model.Job;
import io.oxmq.model.JobOptions;

import java.time.Duration;

public class OrderProducer {
    public static void main(String[] args) {
        // Build the Queue
        OxmqQueue<OrderInvoice> queue = OxmqQueue.<OrderInvoice>builder()
                .name("order-invoices")
                .redisUri("redis://localhost:6379")
                .payloadClass(OrderInvoice.class)
                .build();

        // Enqueue with 5s delay, 3 retry attempts, exponential backoff, and KeepJobs memory pruning
        Job<OrderInvoice> job = queue.add(
                "generate-pdf",
                new OrderInvoice("ord_101", "alice@example.com", 149.50),
                JobOptions.builder()
                        .delay(Duration.ofSeconds(5))
                        .attempts(3)
                        .exponentialBackoff(Duration.ofSeconds(1), Duration.ofSeconds(30))
                        .removeOnComplete(KeepJobs.of(1000, Duration.ofHours(2)))
                        .build()
        );

        System.out.println("Enqueued job ID: " + job.getId());
    }
}

📥 4. Consume Jobs with Virtual Threads (Java 21+) / Platform Threads (Java 17) ​

Create an OxmqWorker to execute tasks concurrently using Java 21 Virtual Threads (with automatic platform thread pool fallback on Java 17):

java
package com.example;

import com.example.model.OrderInvoice;
import io.oxmq.OxmqWorker;

import java.time.Duration;

public class OrderWorker {
    public static void main(String[] args) throws InterruptedException {
        OxmqWorker<OrderInvoice> worker = OxmqWorker.<OrderInvoice>builder()
                .queueName("order-invoices")
                .redisUri("redis://localhost:6379")
                .payloadClass(OrderInvoice.class)
                .concurrency(50) // 50 concurrent Virtual Threads (or platform threads on Java 17)
                .lockDuration(Duration.ofSeconds(30))
                .processor(job -> {
                    OrderInvoice invoice = job.getData();
                    System.out.printf("[%s] Processing order %s ($%.2f) on thread %s%n",
                            job.getId(), invoice.orderId(), invoice.amount(), Thread.currentThread());

                    // Virtual threads unmount during blocking I/O (DB, HTTP, Disk)
                    Thread.sleep(500); 

                    // Return any serializable result or null
                    return "Invoice PDF generated: /invoices/" + invoice.orderId() + ".pdf";
                })
                .build();

        worker.start();
        System.out.println("Worker started. Listening for jobs...");

        // Graceful shutdown on JVM exit
        Runtime.getRuntime().addShutdownHook(new Thread(worker::close));
    }
}

⚡ What Happens Under the Hood? ​

  1. Atomic Ingestion: The producer invokes BullMQ's addDelayedJob-6.lua script, pushing the job into Redis with delayed maturity.
  2. Auto-Promotion: BullMQ Lua scripts check the Redis sorted set bull:order-invoices:delayed and atomically move matured jobs to bull:order-invoices:wait.
  3. Virtual Thread Worker: The OxmqWorker pulls ready jobs via moveToActive-11.lua and dispatches each job to an unpinned Virtual Thread (or platform thread pool on Java 17).
  4. Heartbeat Lock Watchdog: An automated background timer extends the job lock via extendLock-2.lua until task completion.
  5. Completion & Cleanup: moveToFinished-14.lua marks the job completed and persists the return value.

Released under the Apache 2.0 / MIT Open-Source Licenses.