Skip to content
Frody edited this page Sep 3, 2026 · 3 revisions

ScopeFlow Architecture

ScopeFlow Reference Documentation

ScopeFlow is a high-throughput context propagation and correlation library designed for Java 21+ applications running on standard thread pools, reactive runtimes, and Project Loom virtual threads.

License Java Maven Central Build Status


Technical Overview

Context propagation in distributed Java microservices has historically relied on java.lang.ThreadLocal storage, primarily exposed through logging frameworks via SLF4J's Mapped Diagnostic Context (MDC). While sufficient for synchronous, single-threaded execution models, this paradigm introduces significant failure modes in modern architectures:

  1. Context Loss Across Async Boundaries: Tasks submitted to ExecutorService, ForkJoinPool, or CompletableFuture execute on worker threads that do not inherit the calling thread's ThreadLocal state unless explicitly instrumented.
  2. Virtual Thread Memory Overhead: Allocating heavy ThreadLocal structures across millions of ephemeral virtual threads degrades carrier-thread scheduling performance and increases garbage collection pressure.
  3. Trace Fragmenting: Bridging technical logging IDs (e.g., correlation IDs) with distributed telemetry (OpenTelemetry Baggage or W3C Trace Context) often requires disjointed interceptors and boilerplate instrumentation.

ScopeFlow resolves these issues by introducing an immutable, stack-based context abstraction (ScopeContext) governed by deterministic AutoCloseable scopes.


Architectural Workflow

The following diagram illustrates how incoming technical and business metadata is captured by ScopeFlow, encapsulated into an immutable context, and dispatched to underlying logging, tracing, and async subsystems:

flowchart TD
    subgraph Ingress["Ingress Layer"]
        REQ["Inbound Request (HTTP, gRPC, Messaging)"]
    end

    subgraph CoreEngine["ScopeFlow Core Runtime"]
        SF["ScopeFlow.open(scopeName, contextMap)"]
        STACK["Thread-Bound Scoped Stack"]
        CTX[("Immutable ScopeContext")]
        SF --> STACK
        STACK --> CTX
    end

    subgraph Bridges["Configured Propagator Bridges"]
        MDC["SLF4J MDC Bridge (Log Correlation)"]
        OTEL["OpenTelemetry Baggage Bridge"]
        MICRO["Micrometer Context Bridge"]
        SCOPED["Java 23 ScopedValue Bridge"]
    end

    subgraph Execution["Target Execution Concurrency"]
        VT["Virtual Threads (Project Loom)"]
        TP["Platform Thread Pools (Executors)"]
        RX["Reactive Streams (Project Reactor)"]
    end

    REQ --> SF
    CTX --> MDC
    CTX --> OTEL
    CTX --> MICRO
    CTX --> SCOPED

    MDC & OTEL & MICRO & SCOPED -.->|Context Restored on Execution| Execution
Loading

Design Principles

  • Deterministic Lifecycle: Every context boundary implements AutoCloseable. Exiting a try-with-resources block guarantees that the enclosing scope is restored, preventing thread-local leakage in pooled environments.
  • Immutability by Default: ScopeContext is unmodifiable. Child scopes inherit parent attributes while isolating modifications to their immediate execution frame.
  • Zero Overhead: In synchronous paths, ScopeFlow avoids unnecessary map allocations, maintaining sub-microsecond latency.
  • Pluggable Architecture: Integrations with SLF4J, OpenTelemetry, Micrometer, and Spring Boot are isolated into standalone modules. Applications only depend on the adapters they actively utilize.

Module Matrix

ScopeFlow is distributed as modular artifacts available on Maven Central under the io.github.frodygr group:

Artifact ID Description Primary Dependencies
scopeflow-bom Bill of Materials for version alignment across all modules None
scopeflow-core Core API, scope lifecycle, immutable context, and task wrappers Java 21+
scopeflow-mdc SLF4J MDC adapter with save/restore stack and key filtering policies SLF4J API
scopeflow-spring-boot-starter Production starter with automatic configuration and Web MVC interceptor Spring Boot 3.2+
scopeflow-spring-boot-autoconfigure Auto-configuration classes and conditional bean definitions Spring Boot 3.2+
scopeflow-otel OpenTelemetry Baggage bridge for distributed trace correlation OpenTelemetry API
scopeflow-micrometer Micrometer Context Propagation adapter for Project Reactor Micrometer Context
scopeflow-scoped ScopedValue and StructuredTaskScope integration (Java 23 preview) Java 23 (Preview)

Quickstart

1. Maven Dependency

Declare the Spring Boot starter in your pom.xml:

<dependency>
    <groupId>io.github.frodygr</groupId>
    <artifactId>scopeflow-spring-boot-starter</artifactId>
    <version>1.0.2</version>
</dependency>

2. Basic Usage

@Service
public class OrderProcessingService {

    private static final Logger log = LoggerFactory.getLogger(OrderProcessingService.class);
    private final ScopeFlow scopeFlow;
    private final ExecutorService executor;

    public OrderProcessingService(ScopeFlow scopeFlow) {
        this.scopeFlow = scopeFlow;
        this.executor = Executors.newVirtualThreadPerTaskExecutor();
    }

    public void processOrder(String orderId, String customerId) {
        // Bind business context for the duration of this execution block
        try (Scope scope = scopeFlow.open("order.process", Map.of(
                "order.id", orderId,
                "customer.id", customerId
        ))) {
            log.info("Starting order validation");
            // Logs include [order.id=ORD-101 customer.id=C-55]

            // Propagate context seamlessly to asynchronous virtual threads
            executor.submit(scopeFlow.wrap(() -> {
                log.info("Executing asynchronous payment settlement");
                // Context is fully intact inside the worker thread
            }));

            executeInternalSteps();
        }
        // Scope exited: previous thread context is automatically restored
    }
}

Documentation Roadmap

Clone this wiki locally