21 — Advanced

Async Execution

RuleSets can be executed asynchronously using CompletableFuture. This enables non-blocking rule evaluation and lets you run independent rule sets in parallel, leveraging the ExecutorService configured in the RuleContext.

Default Executor

By default, rulii uses a fixed thread pool sized to the number of available processors. This provides sensible concurrency without requiring explicit configuration.

Basic Async Execution

RuleSet<?> ruleSet = RuleSet.builder()
    .with("AsyncRules")
    .rule(/* ... rules ... */)
    .build();

Bindings bindings = Bindings.builder().standard();
bindings.bind("name", "Alice");

// Run asynchronously
CompletableFuture<?> future = ruleSet.runAsync(bindings);

// Wait for result
future.join();

// Or use callbacks
future.thenAccept(result -> {
    System.out.println("Rules completed!");
});

Custom ExecutorService

You can provide your own ExecutorService to control the thread pool size and behavior:

ExecutorService executor = Executors.newFixedThreadPool(4);

RuleContext ctx = RuleContext.builder()
    .executorService(executor)
    .build(bindings);

CompletableFuture<?> future = ruleSet.runAsync(ctx);

Use Cases

Parallel Rule Sets

Run independent rule sets concurrently for faster evaluation

Non-Blocking Validation

Validate inputs without blocking the calling thread

Thread Safety Warning

Caution: Shared Mutable Bindings

Be careful when sharing mutable Bindings across threads. If multiple async rule sets modify the same bindings concurrently, you may encounter race conditions. Use separate bindings per thread or ensure proper synchronization.