From 30481db91d92c393a14e3f420386979be06b167b Mon Sep 17 00:00:00 2001 From: Luqman Saeed Date: Mon, 29 Dec 2025 12:31:00 +0000 Subject: [PATCH 1/6] Revert HTF simulation strategy --- README.md | 380 +++++++++++------- docker-compose-c4.yml | 4 +- docker-compose-g1.yml | 4 +- spotless/java-formatter.xml | 126 ++++++ .../trader/aeron/MarketDataPublisher.java | 9 +- .../trader/pressure/AllocationMode.java | 8 +- .../pressure/MemoryPressureService.java | 109 +++-- src/main/webapp/index.html | 5 +- .../trader/pressure/AllocationModeTest.java | 40 +- .../rest/MemoryPressureResourceTest.java | 2 +- start-comparison.sh | 5 +- start.sh | 13 +- 12 files changed, 471 insertions(+), 234 deletions(-) create mode 100644 spotless/java-formatter.xml diff --git a/README.md b/README.md index b7248da..d33369c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # TradeStreamEE: High-Frequency Trading Reference Architecture -**TradeStreamEE** demonstrates how Jakarta EE applications can achieve low-latency, high-throughput performance by combining modern messaging (Aeron), efficient serialization (SBE), and a concurrent garbage collector (Azul C4). +TradeStreamEE demonstrates how Jakarta EE applications can achieve low-latency, high-throughput performance by combining modern messaging (Aeron), efficient serialization (SBE), and a concurrent garbage collector like Azul C4. -It simulates a high-frequency trading dashboard that ingests tens of thousands of market data messages per second, processes them in real-time, and broadcasts updates to a web frontendβ€”without the latency spikes associated with traditional Java garbage collection. +The application simulates a high-frequency trading dashboard that ingests tens of thousands of market data messages per second, processes them in real-time, and broadcasts updates to a web frontend without the latency spikes associated with traditional Java garbage collection. -## ⚑ The Core Technologies +## Core Technologies -TradeStreamEE achieves high performance by combining four key technologies: +TradeStreamEE combines four key technologies: ### Aeron (Transport) @@ -14,7 +14,7 @@ Ultra-low latency messaging that bypasses the network stack when components run ### SBE (Serialization) -Simple Binary Encoding - the financial industry standard for high-frequency trading. Encodes data as compact binary rather than human-readable text, eliminating parsing overhead and reducing memory allocation. +Simple Binary Encoding is the financial industry standard for high-frequency trading. Encodes data as compact binary rather than human-readable text, eliminating parsing overhead and reducing memory allocation. ### Payara Micro (Jakarta EE Runtime) @@ -22,65 +22,49 @@ A cloud-native Jakarta EE 11 application server that provides Jakarta CDI for de ### Azul Platform Prime (Runtime) -A JVM with the C4 garbage collector that performs cleanup concurrently with application execution, avoiding the "stop-the-world" pauses that cause latency spikes in traditional JVMs. +A JVM with the C4 garbage collector that performs cleanup concurrently with application execution, avoiding the stop-the-world pauses that cause latency spikes in traditional JVMs. -**How they work together:** Payara Micro manages the Aeron publisher/subscriber lifecycle via CDI. The publisher encodes market data into binary using SBE, sends it through Aeron's shared memory transport, and the subscriber decodes it without allocating Java objects. This minimal garbage generation lets C4's concurrent collection easily handle the cleanup, maintaining flat latency even at high throughput. +Integration: Payara Micro manages the Aeron publisher/subscriber lifecycle via CDI. The publisher encodes market data into binary using SBE, sends it through Aeron's shared memory transport, and the subscriber decodes it without allocating Java objects. This minimal garbage generation allows C4's concurrent collection to handle cleanup while maintaining flat latency at high throughput. -## πŸš€ The Rationale: Why This Project Exists +## Project Motivation -Enterprise Java applications often struggle with two competing requirements: +Enterprise Java applications must often balance two competing requirements: -1. **High Throughput:** Ingesting massive data streams (IoT, Financial Data). -2. **Low Latency:** Processing that data without "Stop-the-World" pauses. +1. High Throughput: Ingesting massive data streams (IoT, Financial Data). +2. Low Latency: Processing data without stop-the-world pauses. -Standard JVMs (using G1GC or ParallelGC) often "hiccup" under high load, causing UI freezes or missed SLAs. **TradeStreamEE** proves that by combining a modern, broker-less transport (**Aeron**) with a pauseless runtime (**Azul C4**), standard Jakarta EE applications can achieve microsecond-level latency and massive throughput. +Standard JVMs (using G1GC or ParallelGC) can exhibit latency spikes under high load, potentially causing UI freezes or missed SLAs. TradeStreamEE demonstrates that by combining a modern, broker-less transport (Aeron) with a pauseless runtime (Azul C4), standard Jakarta EE applications can achieve microsecond-level latency and high throughput. -### The "A/B" Comparison +### Comparison Methodology -This project enables side-by-side JVM comparison with identical architectural choices: +This project facilitates a side-by-side JVM comparison using identical architectural choices: -* **Both clusters** use **AERON IPC + Zero-Copy SBE** by default (optimized architecture) -* **Both clusters** can optionally run **DIRECT mode** (naive string processing) via `TRADER_INGESTION_MODE` flag -* **The key difference** is the JVM: Azul C4 (pauseless) vs Standard G1GC (stop-the-world) +* Architecture: Both clusters use AERON IPC + Zero-Copy SBE by default. +* Ingestion: Both clusters support DIRECT mode (naive string processing) via the `TRADER_INGESTION_MODE` flag. +* Variable: The only difference is the JVM (Azul C4 vs Standard G1GC). -This isolates the GC as the variable, letting you see how the same application behaves under different garbage collectors. +This isolation ensures that observed performance differences are attributable solely to the Garbage Collector. -## 🚦 Quick Start +## Quick Start ### Primary Use Case: Side-by-Side JVM Comparison -**Why this matters:** Most benchmarking tools run tests serially, start JVM A, test, shut down, start JVM B, test, then manually compare spreadsheets. That's not how real systems behave. - -TradeStreamEE deploys both JVMs simultaneously, enabling you to see real-time behavior differences under identical conditions. - -**The key point:** Both clusters run the **exact same WAR file**, same code, same configuration, same workload. The **only difference** is the JVM. This isolates the garbage collector as the sole variable, making the comparison fair and meaningful. +TradeStreamEE enables side-by-side JVM comparison by deploying both clusters simultaneously under identical workloads. Both clusters execute the same application binary and configuration, isolating the garbage collector as the sole variable. This approach allows for real-time observation of performance differences in a shared environment, providing a more objective comparison than traditional serial benchmarking. ```bash ./start-comparison.sh all ``` -**What this does:** - -1. Builds and deploys **Azul C4 cluster** (3 instances, ports 8080-8083) -2. Builds and deploys **G1GC cluster** (3 instances, ports 9080-9083) -3. Starts **Prometheus** for metrics collection -4. Starts **Grafana** with pre-configured JVM comparison dashboards -5. Starts **Loki/Promtail** for centralized logging +This command builds and deploys both the Azul C4 cluster (ports 8080-8083) and the G1GC cluster (ports 9080-9083), along with the complete monitoring stack (Prometheus, Grafana, Loki). -**Then open both URLs in separate browser tabs:** +Once deployed, access the applications: -- **C4 Cluster:** http://localhost:8080/trader-stream-ee/ -- **G1 Cluster:** http://localhost:9080/trader-stream-ee/ +- C4 Cluster: http://localhost:8080/trader-stream-ee/ +- G1 Cluster: http://localhost:9080/trader-stream-ee/ -**Watch the "GC Pause Time (Live)" chart** to see the difference: +The "GC Pause Time (Live)" chart in Grafana will demonstrate the performance characteristics: C4 typically maintains a consistent latency profile, while G1GC may exhibit spikes and sawtooth patterns under load. -| Metric | Azul C4 | G1GC | What You'll See | -|:-------------------------|:-------------------|:------------------|:------------------------------------------------------------------| -| **GC Pause Time (Live)** | Flatline | Spikes | C4 maintains consistent latency; G1GC shows stop-the-world pauses | -| **Heap Usage** | Smooth oscillation | Sawtooth patterns | Different collection strategies visualized in real-time | -| **Under Load** | Barely moves | Jitter increases | Apply stress via UI and watch the gap widen | - -**Other options:** +Other options: - `./start-comparison.sh` - Clusters only, no monitoring stack (faster for rapid development) - `./stop-comparison.sh` - Stop all comparison services @@ -98,45 +82,44 @@ Use `./start.sh` for testing individual configurations or architectural modes. T | Fixing Legacy Code | `./start.sh azul-direct` | Azul Prime (C4) | Direct (Heavy) | Show how C4 stabilizes high-allocation apps without code changes | | Optimizing Standard Java | `./start.sh standard-aeron` | Standard JDK (G1GC) | Aeron (Optimized) | Test if architectural optimization helps G1GC performance | -**Utilities:** +Utilities: - `./start.sh logs` - View live logs - `./start.sh stop` - Stop containers - `./start.sh clean` - Deep clean (remove volumes/images) -## πŸ—οΈ Technical Architecture +## Technical Architecture -The application implements a **Hybrid Architecture**: +The application implements a Hybrid Architecture: -1. **Ingestion Layer (Broker-less):** - * Uses **Aeron IPC** (Inter-Process Communication) via an Embedded Media Driver. +1. Ingestion Layer (Broker-less): + * Uses Aeron IPC (Inter-Process Communication) via an Embedded Media Driver. * Bypasses the network stack for ultra-low latency between components. -2. **Serialization Layer (Zero-Copy):** - * Uses **Simple Binary Encoding (SBE)**. +2. Serialization Layer (Zero-Copy): + * Uses Simple Binary Encoding (SBE). * Decodes messages directly from memory buffers (Flyweight pattern) without allocating Java Objects, reducing GC pressure. -3. **Application Layer (Jakarta EE 11):** - * **Payara Micro 7** serves as the container. - * **CDI** manages the lifecycle of the Aeron Publisher and Subscriber. - * **WebSockets** push updates to the browser. -4. **Runtime Layer:** - * **Azul Platform Prime** uses the **C4 Collector** to clean up the "garbage" created by the WebSocket layer concurrently, ensuring a flat latency profile. - -## πŸ› οΈ Tech Stack +3. Application Layer (Jakarta EE 11): + * Payara Micro 7 serves as the container. + * CDI manages the lifecycle of the Aeron Publisher and Subscriber. + * Jakarta Concurrency 3.1 leverages Virtual Threads for high-throughput memory pressure simulation. + * WebSockets push updates to the browser. +4. Runtime Layer: + * Azul Platform Prime uses the C4 Collector to clean up the "garbage" created by the WebSocket layer concurrently, ensuring a flat latency profile. -| Component | Technology | Role | -|:---------------|:----------------------------------------|:----------------------------------------| -| **Runtime** | **Azul Platform Prime** (Zulu Prime 21) | The Pauseless JVM engine. | -| **App Server** | **Payara Micro 7** (Jakarta EE 11) | Cloud-native Jakarta EE runtime. | -| **Transport** | **Aeron** | Low-latency, high-throughput messaging. | -| **Encoding** | **SBE (Simple Binary Encoding)** | Binary serialization (FIX standard). | -| **Frontend** | **HTML5 / Chart.js** | Real-time visualization via WebSockets. | -| **Build** | **Docker / Maven** | Containerized deployment. | +## Tech Stack -## πŸ” Understanding the Modes +| Component | Technology | Role | +|:-----------|:------------------------------------|:----------------------------------------| +| Runtime | Azul Platform Prime (Zulu Prime 21) | The Pauseless JVM engine. | +| App Server | Payara Micro 7 (Jakarta EE 11) | Cloud-native Jakarta EE runtime. | +| Transport | Aeron | Low-latency, high-throughput messaging. | +| Encoding | SBE (Simple Binary Encoding) | Binary serialization (FIX standard). | +| Frontend | HTML5 / Chart.js | Real-time visualization via WebSockets. | +| Build | Docker / Maven | Containerized deployment. | -This demo supports two ingestion architectures that you can use with **either JVM**. Set the `TRADER_INGESTION_MODE` environment variable (`AERON` or `DIRECT`) to switch between them. +## Ingestion Architectures -**Important:** Both Azul C4 and G1GC clusters can run either mode. This lets you test whether architectural optimization (AERON) helps G1GC performance, or how C4 handles high-allocation legacy code (DIRECT). +The application supports two ingestion architectures, configurable via the `TRADER_INGESTION_MODE` environment variable (`AERON` or `DIRECT`). Both Azul C4 and G1GC clusters can run either mode, allowing for flexible performance testing. ```mermaid graph TD @@ -161,45 +144,47 @@ graph TD class A1,A2,A3,A4,A5,A6 optimized ``` -### 1\. DIRECT Mode (The "Heavy" Path) +### DIRECT Mode (High Allocation Path) + +Goal: Simulate a standard, naive enterprise application with high object allocation rates. -**Goal:** Simulate a standard, naive enterprise application with high object allocation rates. -**Use for:** Stress-testing GC behavior under high allocation pressure. +Use Case: Stress-testing GC behavior under high allocation pressure. -**How it works:** +Implementation: -1. **Publisher** generates synthetic market data as POJOs -2. **Allocation** converts data to JSON `String` using `StringBuilder` (high allocation) -3. **Artificial Load** wraps JSON in 1KB padding to stress the Garbage Collector -4. **Transport** via direct method call to `MarketDataBroadcaster` -5. **WebSocket** pushes heavy JSON to browser +1. Publisher generates synthetic market data as POJOs +2. Allocation converts data to JSON String using StringBuilder (high allocation) +3. Artificial Load wraps JSON in 1KB padding to stress the Garbage Collector +4. Transport via direct method call to MarketDataBroadcaster +5. WebSocket pushes heavy JSON to browser -**Performance Characteristics:** +Performance Characteristics: -- **High Allocation:** Gigabytes of temporary String objects per second -- **GC Pressure:** Frequent pauses on G1GC; C4 handles it better but still creates work +- High Allocation: Gigabytes of temporary String objects per second +- GC Pressure: Frequent pauses on G1GC; C4's concurrent collection avoids stop-the-world pauses but still performs work -### 2\. AERON Mode (The "Optimized" Path, Default) +### AERON Mode (Optimized Path, Default) -**Goal:** Low-latency financial pipeline using off-heap memory and zero-copy semantics. -**Use for:** Production-grade performance with minimal GC impact. +Goal: Low-latency financial pipeline using off-heap memory and zero-copy semantics. -**How it works:** +Use Case: Production-grade performance with minimal GC impact. -1. **Publisher** generates synthetic market data -2. **SBE Encoder** writes binary format to off-heap direct buffer (zero-copy) -3. **Aeron IPC** publishes to shared memory ring buffer (kernel bypass) -4. **Fragment Handler** reads using SBE "Flyweights" (reusable views, no allocation) -5. **Transformation** converts to compact JSON for WebSocket -6. **WebSocket** pushes lightweight JSON to browser +Implementation: -**Performance Characteristics:** +1. Publisher generates synthetic market data +2. SBE Encoder writes binary format to off-heap direct buffer (zero-copy) +3. Aeron IPC publishes to shared memory ring buffer (kernel bypass) +4. Fragment Handler reads using SBE "Flyweights" (reusable views, no allocation) +5. Transformation converts to compact JSON for WebSocket +6. WebSocket pushes lightweight JSON to browser -- **Low Allocation:** Almost no garbage in the ingestion hot-path -- **High Throughput:** Aeron IPC handles millions of messages/sec with sub-microsecond latency -- **Both JVMs benefit** from reduced allocation, but C4 maintains flat latency profile +Performance Characteristics: -## βš™οΈ Configuration & Tuning +- Low Allocation: Almost no garbage in the ingestion hot-path +- High Throughput: Aeron IPC handles millions of messages/sec with sub-microsecond latency +- Both JVMs benefit from reduced allocation, but C4 maintains flat latency profile + +## Configuration & Tuning You can tweak the performance characteristics via `docker-compose.yml` or the `.env` file (if created). @@ -214,12 +199,12 @@ Controls how data moves from the Publisher to the Processor. Heap size varies by deployment type: -| Deployment | Dockerfiles | Heap Size | Reason | -|:--------------------------------------|:------------------------------------------------|:----------|:--------------------------------------------------------| -| **Single Instance** (`start.sh`) | `Dockerfile`, `Dockerfile.standard` | 8GB | Full heap for maximum throughput | -| **Clustered** (`start-comparison.sh`) | `Dockerfile.scale`, `Dockerfile.scale.standard` | 4GB | Balanced for 3-instance deployments (~12GB per cluster) | +| Deployment | Dockerfiles | Heap Size | Reason | +|:----------------------------------|:------------------------------------------------|:----------|:--------------------------------------------------------| +| Single Instance (`start.sh`) | `Dockerfile`, `Dockerfile.standard` | 8GB | Full heap for maximum throughput | +| Clustered (`start-comparison.sh`) | `Dockerfile.scale`, `Dockerfile.scale.standard` | 4GB | Balanced for 3-instance deployments (~12GB per cluster) | -**Common JVM options:** +Common JVM options: ```dockerfile # Azul Prime (C4) - 8GB single instance example @@ -229,14 +214,14 @@ ENV JAVA_OPTS="-Xms8g -Xmx8g -XX:+AlwaysPreTouch -XX:+UseTransparentHugePages -D ENV JAVA_OPTS="-Xms4g -Xmx4g -XX:+UseG1GC -XX:+AlwaysPreTouch -XX:+UseTransparentHugePages -Djava.net.preferIPv4Stack=true" ``` -**Infrastructure improvements:** +Infrastructure improvements: -- **Pre-touch Memory** (`-XX:+AlwaysPreTouch`): Pre-allocates heap pages to eliminate runtime allocation overhead -- **Transparent Huge Pages** (`-XX:+UseTransparentHugePages`): Reduces TLB misses for large memory operations -- **GC Logging**: Detailed event logging with decorators for analysis -- **Rate-Limited Logging**: Prevents log flooding during high-throughput operations +- Pre-touch Memory (`-XX:+AlwaysPreTouch`): Pre-allocates heap pages to eliminate runtime allocation overhead +- Transparent Huge Pages (`-XX:+UseTransparentHugePages`): Reduces TLB misses for large memory operations +- GC Logging: Detailed event logging with decorators for analysis +- Rate-Limited Logging: Prevents log flooding during high-throughput operations -**Note:** Azul Platform Prime uses C4 by default; we don't specify `-XX:+UseZGC` since C4 is the native, optimized collector for Azul Prime. +Note: Azul Platform Prime uses C4 by default; we don't specify `-XX:+UseZGC` since C4 is the native, optimized collector for Azul Prime. ### GC Monitoring & Stress Testing @@ -244,55 +229,68 @@ The application includes comprehensive GC monitoring and memory pressure testing #### GC Statistics Collection -**GCStatsService** collects real-time garbage collection metrics via JMX MXBeans: +GCStatsService collects real-time garbage collection metrics via JMX MXBeans: + +* Collection Metrics: Total collection count and time for each GC type +* Pause Time Analysis: Individual pause durations with percentile calculations (P50, P95, P99, P99.9, Max) +* Memory Usage: Heap memory utilization (total, used, free) +* Recent Pause History: Last 100 pause times for trend analysis +* GC Phase Breakdown: Sub-phase timing analysis for detailed performance investigation (vendor-specific) + +#### Memory Pressure Stress Testing -* **Collection Metrics**: Total collection count and time for each GC type -* **Pause Time Analysis**: Individual pause durations with percentile calculations (P50, P95, P99, P99.9, Max) -* **Memory Usage**: Heap memory utilization (total, used, free) -* **Recent Pause History**: Last 100 pause times for trend analysis +MemoryPressureService generates controlled memory allocation to create realistic GC stress: -#### Memory Pressure Testing +Stress Test Patterns: -**MemoryPressureService** provides controlled memory allocation to stress test GC performance: +The service rotates through four high-churn allocation patterns designed to maximize Garbage Collection pressure: -**Allocation Modes:** +* String Churn: High-frequency creation and concatenation of short-lived Strings. +* Byte Array Churn: Rapid allocation and discard of primitive byte arrays. +* Object Graph Churn: Creation of nested object structures to stress reference tracing. +* Collection Churn: High-volume addition/removal of elements in standard Java Collections. -* **OFF**: No additional allocation -* **LOW**: 1 MB/sec - Light pressure -* **MEDIUM**: 10 MB/sec - Moderate pressure -* **HIGH**: 500 MB/sec - Heavy pressure -* **EXTREME**: 2 GB/sec - Extreme pressure +Allocation Modes with Coordinated Bursts: -Each mode allocates byte arrays in a background thread to create realistic memory pressure, allowing observation of: +* OFF: No additional allocation +* LOW: 2 MB/sec - Light pressure (3x bursts every 5 seconds) +* MEDIUM: 20 MB/sec - Moderate pressure (3x bursts every 5 seconds) +* HIGH: 1 GB/sec - Heavy pressure (3x bursts every 5 seconds) +* EXTREME: 4 GB/sec - Extreme pressure (3x bursts every 5 seconds) -* C4's concurrent collection vs G1GC's "stop-the-world" pauses -* Latency impact under increasing memory pressure -* Throughput degradation patterns +Burst Scenarios: All active modes include coordinated allocation bursts (3x multiplier every 5 seconds) to simulate market events like flash crashes, sudden volume spikes, or news-driven trading surges. + +Each mode uses parallel virtual threads to generate load, allowing observation of: + +* C4's concurrent collection vs G1GC's "stop-the-world" pauses under heavy allocation +* Latency impact during burst scenarios +* Throughput degradation patterns with different object types +* Long-lived object promotion patterns (tenured generation stress) #### GC Challenge Mode -The web UI includes **GC Challenge Mode** controls that allow: +The web UI includes GC Challenge Mode controls that allow: * Real-time switching between allocation modes -* Visual feedback showing current stress level -* Side-by-side pause time visualization -* Immediate observation of collector behavior under load +* Visual feedback showing current stress level and burst activity +* Side-by-side pause time visualization with phase breakdown +* Immediate observation of collector behavior under realistic load -This feature enables live demonstration of how Azul C4 maintains low pause times even under extreme memory pressure, while G1GC shows increasingly long pauses. +This feature enables live demonstration of collector behavior under realistic memory pressure with coordinated bursts, allowing comparison of C4's pause times versus G1GC's behavior during market event simulations. -## πŸ“Š Monitoring & Observability +## Monitoring & Observability When running `./start-comparison.sh all`, the following monitoring stack is deployed: -| Component | Access | Purpose | -|:----------------------|:------------------------------------|:------------------------------| -| **Grafana Dashboard** | http://localhost:3000 (admin/admin) | JVM comparison dashboards | -| **Prometheus** | http://localhost:9090 | Metrics collection | -| **Loki** | http://localhost:3100 | Log aggregation | -| **C4 Application** | http://localhost:8080 (Traefik LB) | Azul C4 cluster (3 instances) | -| **G1 Application** | http://localhost:9080 (Traefik LB) | G1GC cluster (3 instances) | +| Component | Access | Purpose | +|:------------------|:------------------------------------|:------------------------------| +| Grafana Dashboard | http://localhost:3000 (admin/admin) | JVM comparison dashboards | +| Prometheus | http://localhost:9090 | Metrics collection | +| Loki | http://localhost:3100 | Log aggregation | +| C4 Application | http://localhost:8080 (Traefik LB) | Azul C4 cluster (3 instances) | +| G1 Application | http://localhost:9080 (Traefik LB) | G1GC cluster (3 instances) | -**Direct instance access:** +Direct instance access: - C4 instances: http://localhost:8081, http://localhost:8082, http://localhost:8083 - G1 instances: http://localhost:9081, http://localhost:9082, http://localhost:9083 @@ -311,10 +309,11 @@ curl http://localhost:8080/api/gc/stats curl http://localhost:9080/api/gc/stats # Available modes: OFF, LOW, MEDIUM, HIGH, EXTREME -# Allocation rates: 0 MB/s, 1 MB/s, 10 MB/s, 500 MB/s, 2 GB/s +# Allocation rates: 0 MB/s, 2 MB/s, 20 MB/s, 1 GB/s, 4 GB/s +# All active modes include 3x allocation bursts every 5 seconds ``` -## πŸ“‚ Project Structure +## Project Structure ```text src/main/ @@ -349,7 +348,7 @@ Dockerfile.scale # Multi-stage build for C4 instances Dockerfile.scale.standard # Build for G1GC instances ``` -## πŸ§ͺ Testing & Quality Assurance +## Testing & Quality Assurance ### Quick Test Execution @@ -367,27 +366,96 @@ Dockerfile.scale.standard # Build for G1GC instances ### Current Test Coverage -**βœ… Working Tests (160/160 passing):** +Working Tests (160/160 passing): -- **Monitoring & GC**: Full coverage of SLA monitoring logic and GC notification handling. -- **REST Resources**: Comprehensive tests for Memory Pressure and GC Stats endpoints. -- **Core Logic**: Validated `AllocationMode` and concurrency configurations. -- **WebSockets**: Verified `MarketDataBroadcaster` functionality and session management. +- Monitoring & GC: Full coverage of SLA monitoring logic and GC notification handling. +- REST Resources: Comprehensive tests for Memory Pressure and GC Stats endpoints. +- Core Logic: Validated `AllocationMode` and concurrency configurations. +- WebSockets: Verified `MarketDataBroadcaster` functionality and session management. -**πŸ“Š Coverage Metrics:** +Coverage Metrics: -- **Tests**: 160 unit tests with 100% pass rate -- **Monitoring Coverage**: >90% (SLAMonitor, GCStatsService) -- **REST API Coverage**: >85% (Resources and DTOs) -- **Instruction Coverage**: High coverage for business logic; integration logic relies on `test.sh`. +- Tests: 160 unit tests with 100% pass rate +- Monitoring Coverage: >90% (SLAMonitor, GCStatsService) +- REST API Coverage: >85% (Resources and DTOs) +- Instruction Coverage: High coverage for business logic; integration logic relies on `test.sh`. ### Test Categories -1. **Unit Tests**: Core component testing in isolation (`src/test/java`) -2. **Integration Tests**: Service layer interactions and resource validation -3. **Performance Tests**: Load testing and benchmarks via scripts -4. **Memory Pressure Tests**: GC behavior validation and stress scenarios - -## πŸ“œ License +1. Unit Tests: Core component testing in isolation (`src/test/java`) +2. Integration Tests: Service layer interactions and resource validation +3. Performance Tests: Load testing and benchmarks via scripts +4. Memory Pressure Tests: GC behavior validation and stress scenarios + +## Trading Terms Glossary + +For readers unfamiliar with high-frequency trading concepts, this glossary explains the domain-specific terms used throughout this project. + +### Market Data & Trading + +| Term | Definition | +|:------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| High-Frequency Trading (HFT) | Automated trading strategies that execute thousands or millions of orders per second, requiring sub-millisecond latency. HFT systems are extremely sensitive to processing delays, making garbage collection pauses a critical performance concern. | +| Order Book / Limit Order Book | A data structure containing all buy and sell orders for a security, organized by price level. Each price level (e.g., $100.50) contains multiple orders waiting to be filled. Order books are updated thousands of times per second in active markets. | +| Bid | The highest price a buyer is willing to pay for a security. | +| Ask | The lowest price a seller is willing to accept. | +| Bid-Ask Spread | The difference between bid and ask prices, representing the cost of immediate execution. | +| Market Tick / Price Tick | A single price update event in the market. High-frequency systems process tens of thousands of ticks per second, with each tick containing price, volume, and timestamp information. | +| L1 Data (Level 1) | Best bid and ask prices only (top of book). | +| L2 Data (Level 2) | Multiple price levels showing aggregate size at each price (market depth). | +| L3 Data (Level 3) | Individual orders at each price level (full order book). | +| Price Ladder | The hierarchical structure of bid and ask prices in an order book. Bid prices decrease as you move away from the best bid; ask prices increase as you move away from the best ask. | +| Crossed Market | An abnormal market condition where the best bid price is higher than the best ask price. This should never occur in normal trading and indicates a data error or system malfunction. | +| Flash Crash | A sudden, severe market downturn followed by rapid recovery, often triggered by algorithmic trading systems. The 2010 Flash Crash saw the Dow Jones drop nearly 1,000 points in minutes. These events create extreme allocation bursts as systems process massive order flow. | + +### Memory & Performance + +| Term | Definition | +|:----------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Allocation Rate | The speed at which a program creates new objects in memory, measured in bytes per second (e.g., "2 GB/sec allocation rate"). Higher allocation rates increase garbage collection pressure. | +| GC Pressure / Memory Pressure | The workload placed on the garbage collector due to object allocation. Higher pressure leads to more frequent garbage collection cycles and potentially longer pause times. | +| Pause Time / Stop-the-World Pause | Duration when a garbage collector halts all application threads to perform cleanup. For HFT systems, even millisecond-level pauses can cause missed trading opportunities or regulatory violations. | +| Concurrent Collection | Garbage collection that runs simultaneously with application threads, avoiding stop-the-world pauses. Azul C4 is a concurrent collector; G1GC uses stop-the-world pauses. | +| Allocation Burst / Burst Scenario | Sudden spikes in memory allocation, simulating events like market opens, news releases, or flash crashes. This project uses 3x allocation multipliers every 5 seconds to simulate these conditions. | +| Tenured Objects / Old Generation | Long-lived objects that survive multiple garbage collection cycles and are promoted to the "old generation" heap region. Order books are typically tenured since they persist across many tick updates. | + +### Data Structures & Patterns + +| Term | Definition | +|:-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Columnar Storage / Columnar Format | Storing data by column rather than by row (e.g., all prices in one array, all volumes in another). This improves cache locality and enables SIMD operations. Our `MarketTickPattern` uses this approach. | +| Flyweight Pattern | A design pattern that reuses objects to minimize memory allocation. SBE codecs use flyweights, they're views over byte buffers rather than allocated objects. | +| Zero-Copy | Data processing without copying bytes between buffers. Aeron IPC and SBE both use zero-copy techniques to minimize allocation and improve throughput. | +| Hierarchical Object Graph | Objects containing references to other objects in a tree structure. Our `OrderBookPattern` creates these: OrderBook, PriceLevel[], Order[]. | + +### Serialization & Messaging + +| Term | Definition | +|:----------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| SBE (Simple Binary Encoding) | A binary serialization format designed for financial trading systems. FIX (Financial Information eXchange) protocol organization standardized it for ultra-low-latency scenarios. | +| Aeron IPC (Inter-Process Communication) | A messaging transport that uses shared memory for same-machine communication, bypassing kernel networking overhead. Achieves sub-microsecond latency. | +| Message Batching | Grouping multiple messages together for efficient processing. Our `MarketTickPattern` simulates batches of 50-200 ticks processed together. | + +### Performance Metrics + +| Term | Definition | +|:----------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Latency | The time delay between an event occurring and the system responding. HFT systems target sub-millisecond (< 1ms) latency for end-to-end trade execution. | +| Throughput | The volume of work completed per unit time (e.g., "1 million messages per second"). HFT systems require both high throughput and low latency simultaneously. | +| P50 (Median) | 50% of requests complete faster than this value. | +| P95 (95th Percentile) | 95% of requests complete faster than this value (1 in 20 is slower). | +| P99 (99th Percentile) | 99% of requests complete faster than this value (1 in 100 is slower). | +| Jitter | Variability in latency. Even with good average latency, high jitter (unpredictable spikes) is unacceptable for HFT. G1GC tends to show jitter under load; C4 maintains consistency. | + +### Trading System Architecture + +| Term | Definition | +|:-------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Ingestion Pipeline / Ingestion Layer | The component responsible for receiving and processing incoming market data feeds. Must handle extreme throughput (millions of messages/sec) with minimal latency. | +| Hot Path / Critical Path | The code execution path that runs most frequently and must be highly optimized. In HFT, the ingestion and order routing paths are hot paths where even nanoseconds matter. | +| Market Event | Significant market occurrences that trigger increased trading activity: market open/close, economic announcements, earnings releases, or sudden price movements. | +| SLA (Service Level Agreement) | Performance guarantees, such as "99.9% of trades execute within 5ms". GC pauses can cause SLA violations if they exceed latency budgets. | + +## License This project is a reference implementation provided for demonstration purposes. diff --git a/docker-compose-c4.yml b/docker-compose-c4.yml index 3469212..989d64e 100644 --- a/docker-compose-c4.yml +++ b/docker-compose-c4.yml @@ -78,7 +78,7 @@ services: - TRADER_INGESTION_MODE=AERON - PAYARA_INSTANCE_NAME=c4-instance-2 - HAZELCAST_MEMBER_NAME=trader-stream-c4-2 - - ENABLE_PUBLISHER=false + - ENABLE_PUBLISHER=true - JVM_TYPE=azul-c4 - JAVA_OPTS=-Xms4g -Xmx4g -Xlog:gc*:file=/opt/payara/gc.log:time,uptime,level,tags:filecount=5,filesize=10M @@ -113,7 +113,7 @@ services: - TRADER_INGESTION_MODE=AERON - PAYARA_INSTANCE_NAME=c4-instance-3 - HAZELCAST_MEMBER_NAME=trader-stream-c4-3 - - ENABLE_PUBLISHER=false + - ENABLE_PUBLISHER=true - JVM_TYPE=azul-c4 - JAVA_OPTS=-Xms4g -Xmx4g -Xlog:gc*:file=/opt/payara/gc.log:time,uptime,level,tags:filecount=5,filesize=10M diff --git a/docker-compose-g1.yml b/docker-compose-g1.yml index 74a7048..c7cecf6 100644 --- a/docker-compose-g1.yml +++ b/docker-compose-g1.yml @@ -79,7 +79,7 @@ services: - TRADER_INGESTION_MODE=AERON - PAYARA_INSTANCE_NAME=g1-instance-2 - HAZELCAST_MEMBER_NAME=trader-stream-g1-2 - - ENABLE_PUBLISHER=false + - ENABLE_PUBLISHER=true - JVM_TYPE=eclipse-temurin-g1 - JAVA_OPTS=-Xms4g -Xmx4g -XX:+UseG1GC @@ -115,7 +115,7 @@ services: - TRADER_INGESTION_MODE=AERON - PAYARA_INSTANCE_NAME=g1-instance-3 - HAZELCAST_MEMBER_NAME=trader-stream-g1-3 - - ENABLE_PUBLISHER=false + - ENABLE_PUBLISHER=true - JVM_TYPE=eclipse-temurin-g1 - JAVA_OPTS=-Xms4g -Xmx4g -XX:+UseG1GC diff --git a/spotless/java-formatter.xml b/spotless/java-formatter.xml new file mode 100644 index 0000000..71f63ff --- /dev/null +++ b/spotless/java-formatter.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java b/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java index 285b07d..b4c30b4 100644 --- a/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java +++ b/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java @@ -553,14 +553,7 @@ private void offer(UnsafeBuffer buffer, int offset, int length, String messageTy consecutiveFailures.set(0); return; } else if (result == Publication.BACK_PRESSURED) { - // Back pressure is normal at high throughput, don't log - retries--; - try { - Thread.sleep(1); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } + continue; } else if (result == Publication.NOT_CONNECTED) { logWarningRateLimited("Publication not connected"); handlePublishFailure(messageType); diff --git a/src/main/java/fish/payara/trader/pressure/AllocationMode.java b/src/main/java/fish/payara/trader/pressure/AllocationMode.java index e8ea920..468244b 100644 --- a/src/main/java/fish/payara/trader/pressure/AllocationMode.java +++ b/src/main/java/fish/payara/trader/pressure/AllocationMode.java @@ -2,10 +2,10 @@ public enum AllocationMode { OFF(0, 0, "No additional allocation"), - LOW(10, 10240, "1 MB/sec - Light pressure"), - MEDIUM(100, 10240, "10 MB/sec - Moderate pressure"), - HIGH(5000, 10240, "500 MB/sec - Heavy pressure"), - EXTREME(20000, 10240, "2 GB/sec - Extreme pressure"); + LOW(20, 10240, "2 MB/sec - Light pressure"), + MEDIUM(200, 10240, "20 MB/sec - Moderate pressure"), + HIGH(10000, 10240, "1 GB/sec - Heavy pressure"), + EXTREME(40000, 10240, "4 GB/sec - Extreme pressure"); private final int allocationsPerIteration; private final int bytesPerAllocation; diff --git a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java index 9946760..95caa41 100644 --- a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java +++ b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java @@ -8,6 +8,7 @@ import jakarta.inject.Inject; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; import java.util.concurrent.ThreadLocalRandom; @@ -27,13 +28,17 @@ public class MemoryPressureService { private volatile boolean running = false; private Future pressureTask; - private long totalBytesAllocated = 0; + private final AtomicLong totalBytesAllocated = new AtomicLong(0); private long lastStatsTime = System.currentTimeMillis(); private final List tenuredObjects = new CopyOnWriteArrayList<>(); private static final int TENURED_TARGET_MB = 1024; private final AtomicLong tenuredBytesAllocated = new AtomicLong(0); + private volatile long lastBurstTime = 0; + private static final long BURST_INTERVAL_MS = 5000; + private static final int BURST_MULTIPLIER = 3; + @Inject @VirtualThreadExecutor private ManagedExecutorService executorService; @PostConstruct @@ -62,7 +67,7 @@ private synchronized void startPressure() { } running = true; - totalBytesAllocated = 0; + totalBytesAllocated.set(0); lastStatsTime = System.currentTimeMillis(); pressureTask = @@ -72,6 +77,7 @@ private synchronized void startPressure() { while (running) { try { + long loopStartTime = System.currentTimeMillis(); AllocationMode mode = currentMode; if (mode == AllocationMode.OFF) { break; @@ -79,7 +85,12 @@ private synchronized void startPressure() { generateGarbage(mode); - Thread.sleep(100); + long executionTime = System.currentTimeMillis() - loopStartTime; + long sleepTime = 100 - executionTime; + + if (sleepTime > 0) { + Thread.sleep(sleepTime); + } logStats(); @@ -104,44 +115,76 @@ private synchronized void stopPressure() { } private void generateGarbage(AllocationMode mode) { - int allocations = mode.getAllocationsPerIteration(); + int baseAllocations = mode.getAllocationsPerIteration(); int bytesPerAlloc = mode.getBytesPerAllocation(); - for (int i = 0; i < allocations; i++) { - int pattern = i % 4; - - switch (pattern) { - case 0: - generateStringGarbage(bytesPerAlloc); - break; - case 1: - generateByteArrayGarbage(bytesPerAlloc); - break; - case 2: - generateObjectGarbage(bytesPerAlloc / 64); - break; - case 3: - generateCollectionGarbage(bytesPerAlloc / 100); - break; + boolean inBurst = false; + if (mode != AllocationMode.OFF) { + long now = System.currentTimeMillis(); + if (now - lastBurstTime >= BURST_INTERVAL_MS) { + inBurst = true; + lastBurstTime = now; + LOGGER.info( + String.format( + "Burst triggered - %dx allocation for %s mode (simulating market event)", + BURST_MULTIPLIER, mode.name())); } + } - if (mode == AllocationMode.HIGH || mode == AllocationMode.EXTREME) { - int chance = (mode == AllocationMode.EXTREME) ? 10 : 2; - if (ThreadLocalRandom.current().nextInt(10000) < chance) { - byte[] longLived = new byte[1024 * 1024]; - ThreadLocalRandom.current().nextBytes(longLived); - tenuredObjects.add(longLived); - tenuredBytesAllocated.addAndGet(1024 * 1024); - } - } + int totalAllocations = inBurst ? baseAllocations * BURST_MULTIPLIER : baseAllocations; + + int numTasks = 4; + int allocationsPerTask = totalAllocations / numTasks; + CompletableFuture[] futures = new CompletableFuture[numTasks]; + + for (int t = 0; t < numTasks; t++) { + final int taskAllocations = + (t == numTasks - 1) + ? totalAllocations - (allocationsPerTask * (numTasks - 1)) + : allocationsPerTask; + + futures[t] = + CompletableFuture.runAsync( + () -> { + for (int i = 0; i < taskAllocations; i++) { + int pattern = i % 4; + + switch (pattern) { + case 0: + generateStringGarbage(bytesPerAlloc); + break; + case 1: + generateByteArrayGarbage(bytesPerAlloc); + break; + case 2: + generateObjectGarbage(bytesPerAlloc / 64); + break; + case 3: + generateCollectionGarbage(bytesPerAlloc / 100); + break; + } + totalBytesAllocated.addAndGet(bytesPerAlloc); + } + }, + executorService); + } + + CompletableFuture.allOf(futures).join(); - totalBytesAllocated += bytesPerAlloc; + if (mode == AllocationMode.HIGH || mode == AllocationMode.EXTREME) { + int chance = (mode == AllocationMode.EXTREME) ? 100 : 20; + if (ThreadLocalRandom.current().nextInt(10000) < chance) { + byte[] longLived = new byte[1024 * 1024]; + ThreadLocalRandom.current().nextBytes(longLived); + tenuredObjects.add(longLived); + tenuredBytesAllocated.addAndGet(1024 * 1024); + } } if (mode == AllocationMode.HIGH || mode == AllocationMode.EXTREME) { while (tenuredBytesAllocated.get() > TENURED_TARGET_MB * 1024L * 1024L) { if (!tenuredObjects.isEmpty()) { - tenuredObjects.remove(0); + tenuredObjects.removeFirst(); tenuredBytesAllocated.addAndGet(-1024 * 1024); } else { break; @@ -186,14 +229,14 @@ private void logStats() { long now = System.currentTimeMillis(); if (now - lastStatsTime >= 5000) { double elapsedSeconds = (now - lastStatsTime) / 1000.0; - double mbPerSec = (totalBytesAllocated / (1024.0 * 1024.0)) / elapsedSeconds; + long allocated = totalBytesAllocated.getAndSet(0); + double mbPerSec = (allocated / (1024.0 * 1024.0)) / elapsedSeconds; LOGGER.info( String.format( "Memory Pressure Stats - Mode: %s | Allocated: %.2f MB/sec | Tenured: %d MB (%d objects)", currentMode, mbPerSec, getTenuredObjectsMB(), getTenuredObjectCount())); - totalBytesAllocated = 0; lastStatsTime = now; } } diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index d9567ee..040314b 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -1173,7 +1173,7 @@

GC Challenge Mode

Waiting... Click to learn -
+
@@ -1547,7 +1547,8 @@

System Log

.catch(error => console.error('Error fetching pressure status:', error)); } - const API_BASE = '/' + window.location.pathname.split('/')[1] + '/api'; + const contextRoot = window.location.pathname.split('/')[1]; + const API_BASE = (contextRoot ? '/' + contextRoot : '') + '/api'; const ALERT_THRESHOLDS = { p99Ms: { warning: 10, critical: 50 }, diff --git a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java index ee63a43..18b3eae 100644 --- a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java +++ b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java @@ -54,10 +54,10 @@ void shouldHaveCorrectAllocationPerIterationValues(AllocationMode mode) { int expected = switch (mode) { case OFF -> 0; - case LOW -> 10; - case MEDIUM -> 100; - case HIGH -> 5000; - case EXTREME -> 20000; + case LOW -> 20; + case MEDIUM -> 200; + case HIGH -> 10000; + case EXTREME -> 40000; }; assertEquals( @@ -109,39 +109,39 @@ void shouldCalculateBytesPerSecondCorrectlyForOffMode() { @Test @DisplayName("Should calculate bytes per second correctly for LOW mode") void shouldCalculateBytesPerSecondCorrectlyForLowMode() { - // 10 allocations * 10240 bytes * 10 iterations/sec = 1,024,000 bytes/sec + // 20 allocations * 10240 bytes * 10 iterations/sec = 2,048,000 bytes/sec assertEquals( - 1_024_000L, AllocationMode.LOW.getBytesPerSecond(), "LOW mode should allocate 1 MB/sec"); + 2_048_000L, AllocationMode.LOW.getBytesPerSecond(), "LOW mode should allocate 2 MB/sec"); } @Test @DisplayName("Should calculate bytes per second correctly for MEDIUM mode") void shouldCalculateBytesPerSecondCorrectlyForMediumMode() { - // 100 allocations * 10240 bytes * 10 iterations/sec = 10,240,000 bytes/sec + // 200 allocations * 10240 bytes * 10 iterations/sec = 20,480,000 bytes/sec assertEquals( - 10_240_000L, + 20_480_000L, AllocationMode.MEDIUM.getBytesPerSecond(), - "MEDIUM mode should allocate 10 MB/sec"); + "MEDIUM mode should allocate 20 MB/sec"); } @Test @DisplayName("Should calculate bytes per second correctly for HIGH mode") void shouldCalculateBytesPerSecondCorrectlyForHighMode() { - // 5000 allocations * 10240 bytes * 10 iterations/sec = 512,000,000 bytes/sec + // 10000 allocations * 10240 bytes * 10 iterations/sec = 1,024,000,000 bytes/sec assertEquals( - 512_000_000L, + 1_024_000_000L, AllocationMode.HIGH.getBytesPerSecond(), - "HIGH mode should allocate 500 MB/sec"); + "HIGH mode should allocate 1 GB/sec"); } @Test @DisplayName("Should calculate bytes per second correctly for EXTREME mode") void shouldCalculateBytesPerSecondCorrectlyForExtremeMode() { - // 20000 allocations * 10240 bytes * 10 iterations/sec = 2,048,000,000 bytes/sec + // 40000 allocations * 10240 bytes * 10 iterations/sec = 4,096,000,000 bytes/sec assertEquals( - 2_048_000_000L, + 4_096_000_000L, AllocationMode.EXTREME.getBytesPerSecond(), - "EXTREME mode should allocate 2 GB/sec"); + "EXTREME mode should allocate 4 GB/sec"); } } @@ -239,19 +239,19 @@ void descriptionsShouldContainPressureLevelIndicators() { @DisplayName("Descriptions should contain rate information") void descriptionsShouldContainRateInformation() { assertTrue( - AllocationMode.LOW.getDescription().contains("1 MB/sec"), + AllocationMode.LOW.getDescription().contains("2 MB/sec"), "LOW description should contain rate information"); assertTrue( - AllocationMode.MEDIUM.getDescription().contains("10 MB/sec"), + AllocationMode.MEDIUM.getDescription().contains("20 MB/sec"), "MEDIUM description should contain rate information"); assertTrue( - AllocationMode.HIGH.getDescription().contains("500 MB/sec"), + AllocationMode.HIGH.getDescription().contains("1 GB/sec"), "HIGH description should contain rate information"); assertTrue( - AllocationMode.EXTREME.getDescription().contains("2 GB/sec"), + AllocationMode.EXTREME.getDescription().contains("4 GB/sec"), "EXTREME description should contain rate information"); } } @@ -283,7 +283,7 @@ void shouldHandleLargeAllocationsCorrectly() { extremeRate > 1_000_000_000L, // 1GB "EXTREME mode should handle large allocations (>1GB/sec)"); - assertEquals(2_048_000_000L, extremeRate, "EXTREME mode should handle exactly 2GB/sec"); + assertEquals(4_096_000_000L, extremeRate, "EXTREME mode should handle exactly 4GB/sec"); } @ParameterizedTest diff --git a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java index 2876a74..a64d7ea 100644 --- a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java @@ -101,7 +101,7 @@ void shouldReturnAllModes() { (Map>) response.getEntity(); assertTrue(entity.containsKey("EXTREME")); assertEquals( - "2 GB/sec - Extreme pressure", + "4 GB/sec - Extreme pressure", ((Map) entity.get("EXTREME")).get("description")); } } diff --git a/start-comparison.sh b/start-comparison.sh index a76f52a..6130883 100755 --- a/start-comparison.sh +++ b/start-comparison.sh @@ -71,9 +71,8 @@ fi # Create networks echo "Creating Docker networks..." docker network create trader-network 2>/dev/null || echo "Network trader-network already exists" -if [ "$MODE" = "all" ]; then - docker network create monitoring 2>/dev/null || echo "Network monitoring already exists" -fi +docker network create monitoring 2>/dev/null || echo "Network monitoring already exists" + echo "βœ“ Networks ready" # Build Docker images diff --git a/start.sh b/start.sh index e64ae76..e9188ef 100755 --- a/start.sh +++ b/start.sh @@ -47,6 +47,8 @@ case "$ACTION" in echo " > Dockerfile (Azul) + MODE=AERON" echo "" MODE=AERON run_compose -f docker-compose.yml up -d --build --force-recreate + echo "" + echo "🌐 Access: http://localhost:8080/trader-stream-ee/" ;; azul-direct) @@ -55,6 +57,8 @@ case "$ACTION" in echo " ℹ️ Observe how C4 handles high-allocation legacy code." echo "" MODE=DIRECT run_compose -f docker-compose.yml up -d --build --force-recreate + echo "" + echo "🌐 Access: http://localhost:8080/trader-stream-ee/" ;; # --- Standard OpenJDK (G1 GC) Scenarios --- @@ -65,6 +69,8 @@ case "$ACTION" in echo " ℹ️ Baseline performance: High allocation on G1GC." echo "" MODE=DIRECT run_compose -f docker-compose-standard.yml up -d --build --force-recreate + echo "" + echo "🌐 Access: http://localhost:8080/trader-stream-ee/" ;; standard-aeron) @@ -73,6 +79,8 @@ case "$ACTION" in echo " ℹ️ Observe if off-heap transport helps G1GC." echo "" MODE=AERON run_compose -f docker-compose-standard.yml up -d --build --force-recreate + echo "" + echo "🌐 Access: http://localhost:8080/trader-stream-ee/" ;; # --- Clustered Scenarios --- @@ -115,6 +123,8 @@ case "$ACTION" in echo " ℹ️ Test cluster with high-allocation legacy mode." echo "" MODE=DIRECT DOCKERFILE=Dockerfile.scale run_compose -f docker-compose-scale.yml up -d --build --force-recreate + echo "" + echo "🌐 Access: http://localhost:8080/trader-stream-ee/" ;; cluster-dynamic) @@ -245,9 +255,6 @@ case "$ACTION" in echo " stop - Stop the application" echo " clean - Stop and clean all containers/volumes" echo "" - echo "Documentation:" - echo " See SCALABILITY.md for clustering details" - echo "" exit 1 ;; esac \ No newline at end of file From e3f4508b5255656e0d7c0519a42cf4c2871964a2 Mon Sep 17 00:00:00 2001 From: Luqman <27694244+pedanticdev@users.noreply.github.com> Date: Mon, 29 Dec 2025 15:27:54 +0000 Subject: [PATCH 2/6] implement alternative gc stress tests (#15) Co-authored-by: Luqman Saeed --- README.md | 93 +- .../trader/pressure/AllocationMode.java | 82 +- .../pressure/MemoryPressureService.java | 397 +++++--- .../payara/trader/pressure/ScenarioType.java | 10 + .../pressure/patterns/AllocationPattern.java | 35 - .../pressure/patterns/HFTPatternRegistry.java | 58 -- .../pressure/patterns/MarketDepthPattern.java | 74 -- .../pressure/patterns/MarketTickPattern.java | 67 -- .../pressure/patterns/OrderBookPattern.java | 103 -- .../payara/trader/rest/GCStatsResource.java | 3 +- .../trader/rest/MemoryPressureResource.java | 90 +- src/main/webapp/blog.html | 66 +- src/main/webapp/images/payara.png | Bin 0 -> 61920 bytes src/main/webapp/index.html | 150 ++- src/main/webapp/presentation.html | 880 ++++++++++++++++++ .../payara/trader/BasicFunctionalityTest.java | 14 +- .../trader/pressure/AllocationModeTest.java | 296 +----- .../patterns/HFTPatternRegistryTest.java | 122 --- .../patterns/MarketDepthPatternTest.java | 129 --- .../patterns/MarketTickPatternTest.java | 99 -- .../patterns/OrderBookPatternTest.java | 91 -- .../trader/rest/GCStatsResourceTest.java | 4 +- .../rest/MemoryPressureResourceTest.java | 43 +- 23 files changed, 1470 insertions(+), 1436 deletions(-) create mode 100644 src/main/java/fish/payara/trader/pressure/ScenarioType.java delete mode 100644 src/main/java/fish/payara/trader/pressure/patterns/AllocationPattern.java delete mode 100644 src/main/java/fish/payara/trader/pressure/patterns/HFTPatternRegistry.java delete mode 100644 src/main/java/fish/payara/trader/pressure/patterns/MarketDepthPattern.java delete mode 100644 src/main/java/fish/payara/trader/pressure/patterns/MarketTickPattern.java delete mode 100644 src/main/java/fish/payara/trader/pressure/patterns/OrderBookPattern.java create mode 100644 src/main/webapp/images/payara.png create mode 100644 src/main/webapp/presentation.html delete mode 100644 src/test/java/fish/payara/trader/pressure/patterns/HFTPatternRegistryTest.java delete mode 100644 src/test/java/fish/payara/trader/pressure/patterns/MarketDepthPatternTest.java delete mode 100644 src/test/java/fish/payara/trader/pressure/patterns/MarketTickPatternTest.java delete mode 100644 src/test/java/fish/payara/trader/pressure/patterns/OrderBookPatternTest.java diff --git a/README.md b/README.md index d33369c..fa3a37f 100644 --- a/README.md +++ b/README.md @@ -239,44 +239,42 @@ GCStatsService collects real-time garbage collection metrics via JMX MXBeans: #### Memory Pressure Stress Testing -MemoryPressureService generates controlled memory allocation to create realistic GC stress: +MemoryPressureService generates controlled memory allocation using scenario-based testing that targets specific garbage collector weaknesses. Rather than generic high-allocation stress, each scenario exposes fundamental algorithmic differences between G1 and C4. -Stress Test Patterns: +Design Principles: -The service rotates through four high-churn allocation patterns designed to maximize Garbage Collection pressure: +* Lower allocation rates (100-500 MB/sec) that allow normal GC behavior rather than pathological thrashing +* Multi-threaded allocation (4 threads) mirroring production web servers and trading systems +* Focus on pause time metrics rather than throughput +* Scenarios that work consistently across 2GB-4GB heap sizes -* String Churn: High-frequency creation and concatenation of short-lived Strings. -* Byte Array Churn: Rapid allocation and discard of primitive byte arrays. -* Object Graph Churn: Creation of nested object structures to stress reference tracing. -* Collection Churn: High-volume addition/removal of elements in standard Java Collections. +Test Scenarios: -Allocation Modes with Coordinated Bursts: +| Scenario | Allocation | Live Set | What It Tests | +|:----------------|:-----------|:-----------------------|:----------------------------------------------------------| +| STEADY_LOAD | 200 MB/sec | 512 MB stable | Baseline young generation collection behavior | +| GROWING_HEAP | 150 MB/sec | 100 MB β†’ 2 GB over 60s | Mixed collection pause scaling with live set size | +| PROMOTION_STORM | 300 MB/sec | 1 GB (50% survival) | Old generation collection efficiency under high promotion | +| FRAGMENTATION | 200 MB/sec | 1 GB fragmented | Compaction behavior with small objects (100-1000 bytes) | +| CROSS_GEN_REFS | 150 MB/sec | 800 MB in old gen | Remembered set overhead from oldβ†’young references | -* OFF: No additional allocation -* LOW: 2 MB/sec - Light pressure (3x bursts every 5 seconds) -* MEDIUM: 20 MB/sec - Moderate pressure (3x bursts every 5 seconds) -* HIGH: 1 GB/sec - Heavy pressure (3x bursts every 5 seconds) -* EXTREME: 4 GB/sec - Extreme pressure (3x bursts every 5 seconds) +Expected Behavior: -Burst Scenarios: All active modes include coordinated allocation bursts (3x multiplier every 5 seconds) to simulate market events like flash crashes, sudden volume spikes, or news-driven trading surges. +* G1: Stop-the-world pauses that scale with live set size, remembered set scanning overhead, compaction pauses under fragmentation +* C4: Zero pauses across all scenarios due to concurrent collection, no remembered sets, concurrent compaction -Each mode uses parallel virtual threads to generate load, allowing observation of: +Each scenario uses 4 parallel virtual threads to generate allocation load. This multi-threaded pattern demonstrates G1's stop-the-world impact when all application threads must pause simultaneously. -* C4's concurrent collection vs G1GC's "stop-the-world" pauses under heavy allocation -* Latency impact during burst scenarios -* Throughput degradation patterns with different object types -* Long-lived object promotion patterns (tenured generation stress) +#### GC Scenario Control -#### GC Challenge Mode +The web UI includes scenario selection controls that allow: -The web UI includes GC Challenge Mode controls that allow: - -* Real-time switching between allocation modes -* Visual feedback showing current stress level and burst activity +* Real-time switching between test scenarios +* Visual feedback showing current scenario and allocation rate * Side-by-side pause time visualization with phase breakdown -* Immediate observation of collector behavior under realistic load +* Observation of collector behavior under specific pathological conditions -This feature enables live demonstration of collector behavior under realistic memory pressure with coordinated bursts, allowing comparison of C4's pause times versus G1GC's behavior during market event simulations. +This feature enables targeted demonstration of G1's architectural limitations versus C4's concurrent collection model. ## Monitoring & Observability @@ -297,22 +295,35 @@ Direct instance access: ### Stress Testing -Use the UI or API to apply memory pressure and observe GC behavior differences: +Use the UI or API to apply memory pressure scenarios and observe GC behavior differences: ```bash -# Apply extreme memory pressure via API -curl -X POST http://localhost:8080/api/pressure/mode/EXTREME # C4 cluster -curl -X POST http://localhost:9080/api/pressure/mode/EXTREME # G1GC cluster +# Apply test scenarios via API +curl -X POST http://localhost:8080/api/pressure/mode/STEADY_LOAD # Baseline test +curl -X POST http://localhost:8080/api/pressure/mode/GROWING_HEAP # Mixed GC scaling +curl -X POST http://localhost:8080/api/pressure/mode/PROMOTION_STORM # Old gen pressure +curl -X POST http://localhost:8080/api/pressure/mode/FRAGMENTATION # Compaction test +curl -X POST http://localhost:8080/api/pressure/mode/CROSS_GEN_REFS # Remembered set test +curl -X POST http://localhost:8080/api/pressure/mode/OFF # Stop pressure # Get current GC statistics -curl http://localhost:8080/api/gc/stats -curl http://localhost:9080/api/gc/stats +curl http://localhost:8080/api/gc/stats # C4 cluster +curl http://localhost:9080/api/gc/stats # G1GC cluster -# Available modes: OFF, LOW, MEDIUM, HIGH, EXTREME -# Allocation rates: 0 MB/s, 2 MB/s, 20 MB/s, 1 GB/s, 4 GB/s -# All active modes include 3x allocation bursts every 5 seconds +# Get current pressure status +curl http://localhost:8080/api/pressure/status ``` +Scenario Details: + +| Scenario | Rate | Target | Purpose | +|:----------------|:---------|:-----------------------|:------------------------------------------| +| STEADY_LOAD | 200 MB/s | 512 MB live set | Tests baseline young GC pause behavior | +| GROWING_HEAP | 150 MB/s | Grows to 2 GB | Tests mixed collection pause scaling | +| PROMOTION_STORM | 300 MB/s | 1 GB with 50% survival | Tests old generation under high promotion | +| FRAGMENTATION | 200 MB/s | 1 GB fragmented | Tests compaction with small objects | +| CROSS_GEN_REFS | 150 MB/s | 800 MB old gen | Tests remembered set scanning overhead | + ## Project Structure ```text @@ -366,7 +377,7 @@ Dockerfile.scale.standard # Build for G1GC instances ### Current Test Coverage -Working Tests (160/160 passing): +Working Tests (170/170 passing): - Monitoring & GC: Full coverage of SLA monitoring logic and GC notification handling. - REST Resources: Comprehensive tests for Memory Pressure and GC Stats endpoints. @@ -375,7 +386,7 @@ Working Tests (160/160 passing): Coverage Metrics: -- Tests: 160 unit tests with 100% pass rate +- Tests: 170 unit tests with 100% pass rate - Monitoring Coverage: >90% (SLAMonitor, GCStatsService) - REST API Coverage: >85% (Resources and DTOs) - Instruction Coverage: High coverage for business logic; integration logic relies on `test.sh`. @@ -412,11 +423,15 @@ For readers unfamiliar with high-frequency trading concepts, this glossary expla | Term | Definition | |:----------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Allocation Rate | The speed at which a program creates new objects in memory, measured in bytes per second (e.g., "2 GB/sec allocation rate"). Higher allocation rates increase garbage collection pressure. | +| Allocation Rate | The speed at which a program creates new objects in memory, measured in bytes per second (e.g., "200 MB/sec allocation rate"). Higher allocation rates increase garbage collection pressure. | | GC Pressure / Memory Pressure | The workload placed on the garbage collector due to object allocation. Higher pressure leads to more frequent garbage collection cycles and potentially longer pause times. | | Pause Time / Stop-the-World Pause | Duration when a garbage collector halts all application threads to perform cleanup. For HFT systems, even millisecond-level pauses can cause missed trading opportunities or regulatory violations. | | Concurrent Collection | Garbage collection that runs simultaneously with application threads, avoiding stop-the-world pauses. Azul C4 is a concurrent collector; G1GC uses stop-the-world pauses. | -| Allocation Burst / Burst Scenario | Sudden spikes in memory allocation, simulating events like market opens, news releases, or flash crashes. This project uses 3x allocation multipliers every 5 seconds to simulate these conditions. | +| Live Set | The total size of objects currently reachable from application roots. Larger live sets increase GC work during marking phases. G1's mixed collection pause time scales with live set size. | +| Promotion / Promotion Rate | Moving objects from young generation to old generation after surviving multiple collections. High promotion rates force frequent old generation collections. | +| Remembered Set | G1 data structure tracking references from old generation to young generation. Scanning remembered sets adds overhead to young GC pauses. C4 has no generational boundaries, eliminating this overhead. | +| Cross-Generational Reference | A reference from an old generation object to a young generation object. G1 must track these via card tables and remembered sets; every such reference update triggers a write barrier. | +| Heap Fragmentation | Memory fragmentation where free space is scattered in small chunks. G1 must pause to compact fragmented regions; C4 compacts concurrently using read barriers. | | Tenured Objects / Old Generation | Long-lived objects that survive multiple garbage collection cycles and are promoted to the "old generation" heap region. Order books are typically tenured since they persist across many tick updates. | ### Data Structures & Patterns diff --git a/src/main/java/fish/payara/trader/pressure/AllocationMode.java b/src/main/java/fish/payara/trader/pressure/AllocationMode.java index 468244b..a9eb0e0 100644 --- a/src/main/java/fish/payara/trader/pressure/AllocationMode.java +++ b/src/main/java/fish/payara/trader/pressure/AllocationMode.java @@ -1,35 +1,79 @@ package fish.payara.trader.pressure; public enum AllocationMode { - OFF(0, 0, "No additional allocation"), - LOW(20, 10240, "2 MB/sec - Light pressure"), - MEDIUM(200, 10240, "20 MB/sec - Moderate pressure"), - HIGH(10000, 10240, "1 GB/sec - Heavy pressure"), - EXTREME(40000, 10240, "4 GB/sec - Extreme pressure"); - - private final int allocationsPerIteration; - private final int bytesPerAllocation; + OFF(0, 0, 0, ScenarioType.NONE, "No allocation"), + + STEADY_LOAD( + 200, // MB/sec allocation rate + 512, // MB live set size + 0, // No growth + ScenarioType.STEADY, + "Steady 200 MB/sec allocation, 512 MB live set - Tests baseline GC behavior"), + + GROWING_HEAP( + 150, // MB/sec allocation rate + 2048, // MB target live set + 60, // seconds to reach target + ScenarioType.GROWING, + "Growing live set 100 MB -> 2 GB over 60s - Tests mixed collection scaling"), + + PROMOTION_STORM( + 300, // MB/sec allocation rate + 1024, // MB live set + 0, // No growth + ScenarioType.PROMOTION, + "High promotion rate (50% survival) - Tests old gen collection efficiency"), + + FRAGMENTATION( + 200, // MB/sec allocation rate + 1024, // MB live set + 0, // No growth + ScenarioType.FRAGMENTATION, + "Small objects, random lifetimes - Tests compaction behavior"), + + CROSS_GEN_REFS( + 150, // MB/sec allocation rate + 800, // MB live set in old gen + 0, // No growth + ScenarioType.CROSS_REF, + "Many old->young references - Tests remembered set overhead"); + + private final int allocationRateMBPerSec; + private final int liveSetSizeMB; + private final int growthDurationSeconds; + private final ScenarioType scenarioType; private final String description; - AllocationMode(int allocationsPerIteration, int bytesPerAllocation, String description) { - this.allocationsPerIteration = allocationsPerIteration; - this.bytesPerAllocation = bytesPerAllocation; + AllocationMode( + int allocationRateMBPerSec, + int liveSetSizeMB, + int growthDurationSeconds, + ScenarioType scenarioType, + String description) { + this.allocationRateMBPerSec = allocationRateMBPerSec; + this.liveSetSizeMB = liveSetSizeMB; + this.growthDurationSeconds = growthDurationSeconds; + this.scenarioType = scenarioType; this.description = description; } - public int getAllocationsPerIteration() { - return allocationsPerIteration; + public int getAllocationRateMBPerSec() { + return allocationRateMBPerSec; } - public int getBytesPerAllocation() { - return bytesPerAllocation; + public int getLiveSetSizeMB() { + return liveSetSizeMB; } - public String getDescription() { - return description; + public int getGrowthDurationSeconds() { + return growthDurationSeconds; + } + + public ScenarioType getScenarioType() { + return scenarioType; } - public long getBytesPerSecond() { - return (long) allocationsPerIteration * bytesPerAllocation * 10; // 10 iterations/sec + public String getDescription() { + return description; } } diff --git a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java index 95caa41..dad90e6 100644 --- a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java +++ b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java @@ -6,18 +6,18 @@ import jakarta.enterprise.concurrent.ManagedExecutorService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.util.ArrayList; -import java.util.List; +import java.util.Deque; +import java.util.LinkedList; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.Future; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Logger; /** - * Service to generate controlled memory pressure for GC stress testing. Based on 1BRC techniques - - * intentional allocation to demonstrate GC behavior. + * Service to generate controlled memory pressure for GC stress testing. Updated to use + * scenario-based testing targeting G1 vs C4 differences. */ @ApplicationScoped public class MemoryPressureService { @@ -31,13 +31,33 @@ public class MemoryPressureService { private final AtomicLong totalBytesAllocated = new AtomicLong(0); private long lastStatsTime = System.currentTimeMillis(); - private final List tenuredObjects = new CopyOnWriteArrayList<>(); - private static final int TENURED_TARGET_MB = 1024; - private final AtomicLong tenuredBytesAllocated = new AtomicLong(0); + // Live set management + private final Deque liveSet = new LinkedList<>(); + private final AtomicLong liveSetBytesAllocated = new AtomicLong(0); - private volatile long lastBurstTime = 0; - private static final long BURST_INTERVAL_MS = 5000; - private static final int BURST_MULTIPLIER = 3; + // For Promotion Storm (thread-safe as multiple threads add to it) + private final Deque promotableObjects = new ConcurrentLinkedDeque<>(); + + // For Cross-Gen Refs scenario - holders in old gen that reference young objects + private final Deque crossRefHolders = new LinkedList<>(); + private final AtomicLong crossRefBytesAllocated = new AtomicLong(0); + + // Scenario state + private final AtomicLong scenarioStartTime = new AtomicLong(0); + + /** + * Holder object that lives in old generation and holds a reference to a young object. Every + * update to youngRef triggers G1's write barrier and remembered set maintenance. + */ + private static class RefHolder { + volatile Object youngRef; // Reference to young gen object - updated frequently + final byte[] padding; // Padding to make holder substantial (~1MB each) + + RefHolder(int paddingSize) { + this.padding = new byte[paddingSize]; + ThreadLocalRandom.current().nextBytes(this.padding); + } + } @Inject @VirtualThreadExecutor private ManagedExecutorService executorService; @@ -57,6 +77,14 @@ public synchronized void setAllocationMode(AllocationMode mode) { if (mode == AllocationMode.OFF) { stopPressure(); } else { + // clear previous state + liveSet.clear(); + liveSetBytesAllocated.set(0); + promotableObjects.clear(); + crossRefHolders.clear(); + crossRefBytesAllocated.set(0); + scenarioStartTime.set(System.currentTimeMillis()); + startPressure(); } } @@ -86,6 +114,7 @@ private synchronized void startPressure() { generateGarbage(mode); long executionTime = System.currentTimeMillis() - loopStartTime; + // Target 10 iterations per second (100ms per iteration) long sleepTime = 100 - executionTime; if (sleepTime > 0) { @@ -103,6 +132,12 @@ private synchronized void startPressure() { } LOGGER.info("Memory pressure generator stopped"); + // Cleanup + liveSet.clear(); + liveSetBytesAllocated.set(0); + promotableObjects.clear(); + crossRefHolders.clear(); + crossRefBytesAllocated.set(0); }); } @@ -115,113 +150,267 @@ private synchronized void stopPressure() { } private void generateGarbage(AllocationMode mode) { - int baseAllocations = mode.getAllocationsPerIteration(); - int bytesPerAlloc = mode.getBytesPerAllocation(); - - boolean inBurst = false; - if (mode != AllocationMode.OFF) { - long now = System.currentTimeMillis(); - if (now - lastBurstTime >= BURST_INTERVAL_MS) { - inBurst = true; - lastBurstTime = now; - LOGGER.info( - String.format( - "Burst triggered - %dx allocation for %s mode (simulating market event)", - BURST_MULTIPLIER, mode.name())); - } + switch (mode.getScenarioType()) { + case STEADY: + executeSteadyLoadScenario(mode); + break; + case GROWING: + executeGrowingHeapScenario(mode); + break; + case PROMOTION: + executePromotionStormScenario(mode); + break; + case FRAGMENTATION: + executeFragmentationScenario(mode); + break; + case CROSS_REF: + executeCrossRefsScenario(mode); + break; + default: + // Do nothing for NONE + break; + } + } + + private void executeSteadyLoadScenario(AllocationMode mode) { + int targetMB = mode.getLiveSetSizeMB(); + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + + // Maintain stable live set (single-threaded) + maintainLiveSet(targetMB); + + // Allocate transient garbage at specified rate across 4 threads + // (100ms iteration = 10 iterations/sec) + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); + } + + private void executeGrowingHeapScenario(AllocationMode mode) { + long startTime = scenarioStartTime.get(); + long elapsed = (System.currentTimeMillis() - startTime) / 1000; // seconds + + int startMB = 100; + int targetMB = mode.getLiveSetSizeMB(); + int duration = mode.getGrowthDurationSeconds(); + + // Calculate current target based on linear growth + int currentTargetMB = + elapsed >= duration + ? targetMB + : startMB + (int) ((targetMB - startMB) * elapsed / duration); + + maintainLiveSet(currentTargetMB); + + // Allocate transient garbage + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); + } + + private void executePromotionStormScenario(AllocationMode mode) { + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + // 50% of allocations should survive to old generation + // Allocate half as transient, half as medium-lived + int transientBytes = bytesPerIteration / 2; + int promotableBytes = bytesPerIteration / 2; + + // Multi-threaded allocation for both transient and promotable + allocateTransientGarbageMultiThreaded(transientBytes, 4); + allocatePromotableGarbageMultiThreaded(promotableBytes, 4); + + // Move from thread-safe queue to local live set management + byte[] promoted; + while ((promoted = promotableObjects.poll()) != null) { + liveSet.add(promoted); + liveSetBytesAllocated.addAndGet(promoted.length); + } + + // Now trim live set if needed (remove oldest) + long targetBytes = mode.getLiveSetSizeMB() * 1024L * 1024L; + while (liveSetBytesAllocated.get() > targetBytes && !liveSet.isEmpty()) { + byte[] removed = liveSet.removeFirst(); + liveSetBytesAllocated.addAndGet(-removed.length); } + } + + private void executeFragmentationScenario(AllocationMode mode) { + int targetMB = mode.getLiveSetSizeMB(); + maintainLiveSet(targetMB); + + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + allocateFragmentationGarbageMultiThreaded(bytesPerIteration, 4); + } + + private void executeCrossRefsScenario(AllocationMode mode) { + // Maintain old gen holders (these will be promoted after surviving GCs) + maintainCrossRefHolders(mode.getLiveSetSizeMB()); + + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + // Create young objects and link them from old gen holders + // This triggers G1's write barriers and remembered set updates + createCrossGenerationalRefsMultiThreaded(bytesPerIteration, 4); + } - int totalAllocations = inBurst ? baseAllocations * BURST_MULTIPLIER : baseAllocations; + /** + * Maintain RefHolder objects that will live in old generation. Each holder has ~1MB padding and a + * reference slot for young objects. + */ + private void maintainCrossRefHolders(int targetMB) { + long targetBytes = targetMB * 1024L * 1024L; + long currentBytes = crossRefBytesAllocated.get(); + + // Add holders if below target + while (currentBytes < targetBytes) { + RefHolder holder = new RefHolder(1024 * 1024); // ~1MB each + crossRefHolders.add(holder); + currentBytes += 1024 * 1024; + crossRefBytesAllocated.set(currentBytes); + } - int numTasks = 4; - int allocationsPerTask = totalAllocations / numTasks; - CompletableFuture[] futures = new CompletableFuture[numTasks]; + // Remove holders if above target + while (currentBytes > targetBytes && !crossRefHolders.isEmpty()) { + crossRefHolders.removeFirst(); + currentBytes -= 1024 * 1024; + crossRefBytesAllocated.set(currentBytes); + } + } - for (int t = 0; t < numTasks; t++) { - final int taskAllocations = - (t == numTasks - 1) - ? totalAllocations - (allocationsPerTask * (numTasks - 1)) - : allocationsPerTask; + /** + * Create young objects and update oldβ†’young references. Each reference update triggers G1's write + * barrier, which marks the card table and adds to remembered sets. This is the overhead we're + * testing - C4 has no remembered sets. + */ + private void createCrossGenerationalRefsMultiThreaded(int totalBytes, int numThreads) { + if (crossRefHolders.isEmpty()) { + return; + } + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; + + // Convert to array for random access from multiple threads + RefHolder[] holders = crossRefHolders.toArray(new RefHolder[0]); + + for (int t = 0; t < numThreads; t++) { futures[t] = CompletableFuture.runAsync( () -> { - for (int i = 0; i < taskAllocations; i++) { - int pattern = i % 4; - - switch (pattern) { - case 0: - generateStringGarbage(bytesPerAlloc); - break; - case 1: - generateByteArrayGarbage(bytesPerAlloc); - break; - case 2: - generateObjectGarbage(bytesPerAlloc / 64); - break; - case 3: - generateCollectionGarbage(bytesPerAlloc / 100); - break; - } - totalBytesAllocated.addAndGet(bytesPerAlloc); + int remaining = bytesPerThread; + while (remaining > 0) { + // Create young object (1-4KB each for variety) + int size = ThreadLocalRandom.current().nextInt(1024, 4097); + if (size > remaining) size = remaining; + byte[] youngObj = new byte[size]; + ThreadLocalRandom.current().nextBytes(youngObj); + + // Update random old gen holder to point to this young object + // This write triggers G1's post-write barrier: + // 1. Marks card table entry as dirty + // 2. Adds to remembered set for later scanning + int idx = ThreadLocalRandom.current().nextInt(holders.length); + holders[idx].youngRef = youngObj; + + remaining -= size; } + totalBytesAllocated.addAndGet(bytesPerThread); }, executorService); } CompletableFuture.allOf(futures).join(); + } - if (mode == AllocationMode.HIGH || mode == AllocationMode.EXTREME) { - int chance = (mode == AllocationMode.EXTREME) ? 100 : 20; - if (ThreadLocalRandom.current().nextInt(10000) < chance) { - byte[] longLived = new byte[1024 * 1024]; - ThreadLocalRandom.current().nextBytes(longLived); - tenuredObjects.add(longLived); - tenuredBytesAllocated.addAndGet(1024 * 1024); - } - } + private void allocateTransientGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; - if (mode == AllocationMode.HIGH || mode == AllocationMode.EXTREME) { - while (tenuredBytesAllocated.get() > TENURED_TARGET_MB * 1024L * 1024L) { - if (!tenuredObjects.isEmpty()) { - tenuredObjects.removeFirst(); - tenuredBytesAllocated.addAndGet(-1024 * 1024); - } else { - break; - } - } - } else if (mode == AllocationMode.OFF || mode == AllocationMode.LOW) { - if (!tenuredObjects.isEmpty()) { - tenuredObjects.clear(); - tenuredBytesAllocated.set(0); - } + for (int t = 0; t < numThreads; t++) { + futures[t] = + CompletableFuture.runAsync( + () -> { + // Each thread allocates its share + byte[] garbage = new byte[bytesPerThread]; + ThreadLocalRandom.current().nextBytes(garbage); + // Object is now eligible for GC + totalBytesAllocated.addAndGet(bytesPerThread); + }, + executorService); } + + // Wait for all threads to complete + CompletableFuture.allOf(futures).join(); } - private void generateStringGarbage(int bytes) { - StringBuilder sb = new StringBuilder(bytes); - for (int i = 0; i < bytes / 10; i++) { - sb.append("GARBAGE"); + private void allocatePromotableGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; + + for (int t = 0; t < numThreads; t++) { + futures[t] = + CompletableFuture.runAsync( + () -> { + // Create objects that live long enough to be promoted + byte[] obj = new byte[bytesPerThread]; + ThreadLocalRandom.current().nextBytes(obj); + promotableObjects.add(obj); + totalBytesAllocated.addAndGet(bytesPerThread); + }, + executorService); } - String garbage = sb.toString(); - } - private void generateByteArrayGarbage(int bytes) { - byte[] garbage = new byte[bytes]; - ThreadLocalRandom.current().nextBytes(garbage); + CompletableFuture.allOf(futures).join(); } - private void generateObjectGarbage(int count) { - List garbage = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - garbage.add(new DummyObject(i, "data-" + i, System.nanoTime())); + private void allocateFragmentationGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; + + for (int t = 0; t < numThreads; t++) { + futures[t] = + CompletableFuture.runAsync( + () -> { + int remaining = bytesPerThread; + while (remaining > 0) { + // Small objects 100-1000 bytes + int size = ThreadLocalRandom.current().nextInt(100, 1001); + if (size > remaining) size = remaining; + byte[] garbage = new byte[size]; + ThreadLocalRandom.current().nextBytes(garbage); + remaining -= size; + } + totalBytesAllocated.addAndGet(bytesPerThread); + }, + executorService); } + + CompletableFuture.allOf(futures).join(); } - private void generateCollectionGarbage(int count) { - List garbage = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - garbage.add(ThreadLocalRandom.current().nextInt()); + private void maintainLiveSet(int targetMB) { + long targetBytes = targetMB * 1024L * 1024L; + long currentBytes = liveSetBytesAllocated.get(); + + // Add objects if below target + while (currentBytes < targetBytes) { + byte[] obj = new byte[1024 * 1024]; // 1 MB object + ThreadLocalRandom.current().nextBytes(obj); + liveSet.add(obj); + currentBytes += 1024 * 1024; + liveSetBytesAllocated.set(currentBytes); + } + + // Remove objects if above target + while (currentBytes > targetBytes && !liveSet.isEmpty()) { + liveSet.removeFirst(); + currentBytes -= 1024 * 1024; + liveSetBytesAllocated.set(currentBytes); } } @@ -234,21 +423,13 @@ private void logStats() { LOGGER.info( String.format( - "Memory Pressure Stats - Mode: %s | Allocated: %.2f MB/sec | Tenured: %d MB (%d objects)", - currentMode, mbPerSec, getTenuredObjectsMB(), getTenuredObjectCount())); + "Memory Pressure Stats - Mode: %s | Allocated: %.2f MB/sec | Live Set: %d MB", + currentMode, mbPerSec, liveSetBytesAllocated.get() / (1024 * 1024))); lastStatsTime = now; } } - public long getTenuredObjectsMB() { - return tenuredBytesAllocated.get() / (1024 * 1024); - } - - public int getTenuredObjectCount() { - return tenuredObjects.size(); - } - @PreDestroy public void shutdown() { LOGGER.info("Shutting down MemoryPressureService"); @@ -262,16 +443,4 @@ public AllocationMode getCurrentMode() { public boolean isRunning() { return running; } - - private static class DummyObject { - private final int id; - private final String data; - private final long timestamp; - - DummyObject(int id, String data, long timestamp) { - this.id = id; - this.data = data; - this.timestamp = timestamp; - } - } } diff --git a/src/main/java/fish/payara/trader/pressure/ScenarioType.java b/src/main/java/fish/payara/trader/pressure/ScenarioType.java new file mode 100644 index 0000000..cc62cc2 --- /dev/null +++ b/src/main/java/fish/payara/trader/pressure/ScenarioType.java @@ -0,0 +1,10 @@ +package fish.payara.trader.pressure; + +public enum ScenarioType { + NONE, + STEADY, + GROWING, + PROMOTION, + FRAGMENTATION, + CROSS_REF +} diff --git a/src/main/java/fish/payara/trader/pressure/patterns/AllocationPattern.java b/src/main/java/fish/payara/trader/pressure/patterns/AllocationPattern.java deleted file mode 100644 index 449452e..0000000 --- a/src/main/java/fish/payara/trader/pressure/patterns/AllocationPattern.java +++ /dev/null @@ -1,35 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -/** - * Interface for HFT allocation patterns simulating realistic trading system memory profiles. - * Implementations create domain-specific object graphs (order books, ticks, depth snapshots) that - * match actual high-frequency trading application allocation behavior. - * - *

Each pattern generates objects approximating a target byte size, though actual allocation may - * vary due to object headers, alignment, and JVM-specific overhead. - */ -public interface AllocationPattern { - - /** - * Allocate objects approximating the specified byte size. - * - *

The implementation creates domain-specific object graphs (e.g., order book levels with order - * arrays, tick batches with primitive arrays) that become garbage after the method returns, - * simulating realistic HFT memory pressure. - * - * @param approximateBytes Target allocation size in bytes. Actual allocation may vary by 10-15% - * due to object headers, array overhead, and alignment padding. - * @return Allocated object that will become garbage after method returns. The specific type - * depends on the pattern implementation. - */ - Object allocate(int approximateBytes); - - /** - * Returns the human-readable name of this allocation pattern. - * - *

Used for logging and metrics to identify which pattern generated allocations. - * - * @return Pattern name (e.g., "OrderBook", "MarketTick", "MarketDepth") - */ - String getName(); -} diff --git a/src/main/java/fish/payara/trader/pressure/patterns/HFTPatternRegistry.java b/src/main/java/fish/payara/trader/pressure/patterns/HFTPatternRegistry.java deleted file mode 100644 index 1ba1d48..0000000 --- a/src/main/java/fish/payara/trader/pressure/patterns/HFTPatternRegistry.java +++ /dev/null @@ -1,58 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import jakarta.enterprise.context.ApplicationScoped; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Registry for HFT allocation patterns with round-robin selection. - * - *

Ensures even distribution of allocation types across patterns, simulating realistic HFT - * workloads where order books, ticks, and depth snapshots are processed in parallel streams. - * - *

Thread-safe for concurrent access from multiple allocation threads (though current - * implementation uses single allocation thread). - */ -@ApplicationScoped -public class HFTPatternRegistry { - - private final List patterns; - private final AtomicInteger roundRobinIndex = new AtomicInteger(0); - - /** Initializes registry with standard HFT allocation patterns. */ - public HFTPatternRegistry() { - this.patterns = - List.of(new OrderBookPattern(), new MarketTickPattern(), new MarketDepthPattern()); - } - - /** - * Selects next pattern using round-robin distribution. - * - *

Thread-safe for concurrent access. Each call advances to the next pattern in sequence, - * ensuring even distribution over time. - * - * @return Next pattern in rotation (OrderBook β†’ Tick β†’ Depth β†’ OrderBook β†’ ...) - */ - public AllocationPattern selectPattern() { - int index = roundRobinIndex.getAndIncrement(); - return patterns.get(Math.abs(index % patterns.size())); - } - - /** - * Returns all registered allocation patterns. - * - * @return Immutable list of patterns in registration order - */ - public List getAllPatterns() { - return patterns; - } - - /** - * Returns the count of registered patterns. - * - * @return Number of patterns (currently 3: OrderBook, Tick, Depth) - */ - public int getPatternCount() { - return patterns.size(); - } -} diff --git a/src/main/java/fish/payara/trader/pressure/patterns/MarketDepthPattern.java b/src/main/java/fish/payara/trader/pressure/patterns/MarketDepthPattern.java deleted file mode 100644 index 15d6b51..0000000 --- a/src/main/java/fish/payara/trader/pressure/patterns/MarketDepthPattern.java +++ /dev/null @@ -1,74 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import java.util.concurrent.ThreadLocalRandom; - -/** - * Simulates L2/L3 market depth snapshots with bid/ask ladders. - * - *

Creates multi-dimensional arrays representing aggregate depth at each price level on both - * sides of the book. Matches real market data feed structures that provide full market depth for - * liquidity analysis. - * - *

Typical allocation: 2 sides Γ— 50 levels Γ— ~60 bytes per level β‰ˆ 6KB per snapshot - */ -public class MarketDepthPattern implements AllocationPattern { - - private static final String[] SYMBOLS = { - "AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "META", "NVDA", "JPM" - }; - - @Override - public Object allocate(int approximateBytes) { - // Target: ~6KB per snapshot (2 sides Γ— 50 levels Γ— ~60 bytes) - // Calculate depth levels to approximate target size - int depthLevels = approximateBytes / 120; // 2 sides Γ— 60 bytes per level - depthLevels = Math.max(10, Math.min(depthLevels, 100)); // Clamp 10-100 - - DepthSnapshot snapshot = new DepthSnapshot(randomSymbol(), depthLevels); - return snapshot; - } - - @Override - public String getName() { - return "MarketDepth"; - } - - private String randomSymbol() { - return SYMBOLS[ThreadLocalRandom.current().nextInt(SYMBOLS.length)]; - } - - /** - * Represents a full market depth snapshot with bid and ask ladders. - * - *

Real trading systems use this to calculate available liquidity, optimal execution prices, - * and market impact. Updated frequently (10-100ms) as orders change. - */ - static class DepthSnapshot { - final String symbol; - final double[] bidPrices; - final int[] bidSizes; - final double[] askPrices; - final int[] askSizes; - final long timestamp; - - DepthSnapshot(String symbol, int depthLevels) { - this.symbol = symbol; - this.bidPrices = new double[depthLevels]; - this.bidSizes = new int[depthLevels]; - this.askPrices = new double[depthLevels]; - this.askSizes = new int[depthLevels]; - this.timestamp = System.nanoTime(); - - double basePrice = 100.0 + ThreadLocalRandom.current().nextDouble(100.0); - double spread = 0.05; // Bid-ask spread - for (int i = 0; i < depthLevels; i++) { - // Bids decrease with depth (best bid is basePrice - spread) - bidPrices[i] = basePrice - spread - (i * 0.01); - bidSizes[i] = ThreadLocalRandom.current().nextInt(100, 10000); - // Asks increase with depth (best ask is basePrice) - askPrices[i] = basePrice + (i * 0.01); - askSizes[i] = ThreadLocalRandom.current().nextInt(100, 10000); - } - } - } -} diff --git a/src/main/java/fish/payara/trader/pressure/patterns/MarketTickPattern.java b/src/main/java/fish/payara/trader/pressure/patterns/MarketTickPattern.java deleted file mode 100644 index c556e74..0000000 --- a/src/main/java/fish/payara/trader/pressure/patterns/MarketTickPattern.java +++ /dev/null @@ -1,67 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import java.util.concurrent.ThreadLocalRandom; - -/** - * Simulates market tick data batches using primitive arrays for efficient allocation. - * - *

Represents high-frequency tick ingestion where prices, volumes, and timestamps arrive in rapid - * batches. Uses parallel primitive arrays (similar to columnar storage) to match real HFT tick - * buffers. - * - *

Typical allocation: 100 ticks Γ— ~40 bytes per tick β‰ˆ 4KB per batch - */ -public class MarketTickPattern implements AllocationPattern { - - private static final String[] SYMBOLS = { - "AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "META", "NVDA", "JPM" - }; - - @Override - public Object allocate(int approximateBytes) { - // Target: ~4KB per batch (100 ticks Γ— ~40 bytes) - // Calculate tick count to approximate target size - int numTicks = approximateBytes / 40; - numTicks = Math.max(50, Math.min(numTicks, 200)); // Clamp 50-200 - - TickBatch batch = new TickBatch(randomSymbol(), numTicks); - return batch; - } - - @Override - public String getName() { - return "MarketTick"; - } - - private String randomSymbol() { - return SYMBOLS[ThreadLocalRandom.current().nextInt(SYMBOLS.length)]; - } - - /** - * Represents a batch of market ticks stored in columnar format. - * - *

Real HFT systems use this structure to efficiently process thousands of ticks per second, - * enabling SIMD operations and cache-friendly sequential access. - */ - static class TickBatch { - final String symbol; - final double[] prices; - final long[] volumes; - final long[] timestamps; - - TickBatch(String symbol, int numTicks) { - this.symbol = symbol; - this.prices = new double[numTicks]; - this.volumes = new long[numTicks]; - this.timestamps = new long[numTicks]; - - double basePrice = 100.0 + ThreadLocalRandom.current().nextDouble(100.0); - for (int i = 0; i < numTicks; i++) { - // Simulate price walking with small random changes - prices[i] = basePrice + ThreadLocalRandom.current().nextDouble(-1.0, 1.0); - volumes[i] = ThreadLocalRandom.current().nextInt(100, 10000); - timestamps[i] = System.nanoTime() + i; - } - } - } -} diff --git a/src/main/java/fish/payara/trader/pressure/patterns/OrderBookPattern.java b/src/main/java/fish/payara/trader/pressure/patterns/OrderBookPattern.java deleted file mode 100644 index ae8e2fb..0000000 --- a/src/main/java/fish/payara/trader/pressure/patterns/OrderBookPattern.java +++ /dev/null @@ -1,103 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import java.util.concurrent.ThreadLocalRandom; - -/** - * Simulates limit order book allocation matching L2/L3 market data structures. - * - *

Creates hierarchical object graphs with price levels containing arrays of orders, mimicking - * real order book data structures used in high-frequency trading systems. Each allocation generates - * a complete order book snapshot with configurable depth. - * - *

Typical allocation: 5 price levels Γ— 20 orders per level β‰ˆ 5KB per order book - */ -public class OrderBookPattern implements AllocationPattern { - - private static final String[] SYMBOLS = { - "AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "META", "NVDA", "JPM" - }; - - @Override - public Object allocate(int approximateBytes) { - // Target: ~5KB per book (5 levels Γ— 20 orders Γ— ~50 bytes per order) - // Calculate orders per level to approximate target size - int numLevels = 5; - int ordersPerLevel = approximateBytes / (numLevels * 250); - ordersPerLevel = Math.max(10, Math.min(ordersPerLevel, 50)); // Clamp 10-50 - - OrderBook book = new OrderBook(randomSymbol(), numLevels, ordersPerLevel); - return book; - } - - @Override - public String getName() { - return "OrderBook"; - } - - private String randomSymbol() { - return SYMBOLS[ThreadLocalRandom.current().nextInt(SYMBOLS.length)]; - } - - /** - * Represents a complete order book snapshot with bid and ask price levels. - * - *

In real HFT systems, this structure is updated thousands of times per second as orders are - * added, modified, or executed. - */ - static class OrderBook { - final String symbol; - final PriceLevel[] levels; - - OrderBook(String symbol, int numLevels, int ordersPerLevel) { - this.symbol = symbol; - this.levels = new PriceLevel[numLevels]; - - double basePrice = 100.0 + ThreadLocalRandom.current().nextDouble(100.0); - for (int i = 0; i < numLevels; i++) { - levels[i] = - new PriceLevel( - basePrice + (i * 0.01), - ordersPerLevel, - i < numLevels / 2 // First half bid, second half ask - ); - } - } - } - - /** - * Represents a single price level in the order book containing multiple orders. - * - *

Each level aggregates orders at the same price point, separated by side (bid/ask). - */ - static class PriceLevel { - final double price; - final Order[] orders; - final boolean isBid; - - PriceLevel(double price, int numOrders, boolean isBid) { - this.price = price; - this.isBid = isBid; - this.orders = new Order[numOrders]; - - for (int i = 0; i < numOrders; i++) { - orders[i] = new Order(ThreadLocalRandom.current().nextInt(100, 10000), System.nanoTime()); - } - } - } - - /** - * Represents an individual order at a price level. - * - *

In production systems, orders also include trader IDs, timestamps, and other metadata. This - * simplified version focuses on allocation profile matching. - */ - static class Order { - final int quantity; - final long timestamp; - - Order(int quantity, long timestamp) { - this.quantity = quantity; - this.timestamp = timestamp; - } - } -} diff --git a/src/main/java/fish/payara/trader/rest/GCStatsResource.java b/src/main/java/fish/payara/trader/rest/GCStatsResource.java index bf4eb25..bb19229 100644 --- a/src/main/java/fish/payara/trader/rest/GCStatsResource.java +++ b/src/main/java/fish/payara/trader/rest/GCStatsResource.java @@ -90,8 +90,7 @@ public Response getComparison() { comparison.put("allocationMode", memoryPressureService.getCurrentMode()); comparison.put( - "allocationRateMBps", - memoryPressureService.getCurrentMode().getBytesPerSecond() / (1024 * 1024)); + "allocationRateMBps", memoryPressureService.getCurrentMode().getAllocationRateMBPerSec()); comparison.put("messageRate", publisher.getMessagesPublished()); List stats = gcStatsService.collectGCStats(); diff --git a/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java b/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java index 5922478..be0d1ad 100644 --- a/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java +++ b/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java @@ -6,12 +6,9 @@ import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.logging.Logger; -import java.util.stream.Collectors; @Path("/pressure") public class MemoryPressureResource { @@ -20,29 +17,6 @@ public class MemoryPressureResource { @Inject private MemoryPressureService pressureService; - public enum StressScenario { - DEMO_BASELINE(AllocationMode.OFF, "Baseline - No artificial stress"), - DEMO_NORMAL(AllocationMode.LOW, "Normal Trading - Light load to show steady-state"), - DEMO_STRESS(AllocationMode.HIGH, "High Stress - Heavy allocation + burst patterns"), - DEMO_EXTREME(AllocationMode.EXTREME, "Extreme Stress - Maximum pressure + tenured pollution"); - - private final AllocationMode mode; - private final String description; - - StressScenario(AllocationMode mode, String description) { - this.mode = mode; - this.description = description; - } - - public AllocationMode getMode() { - return mode; - } - - public String getDescription() { - return description; - } - } - @GET @Path("/status") @Produces(MediaType.APPLICATION_JSON) @@ -53,7 +27,9 @@ public Response getStatus() { status.put("currentMode", currentMode.name()); status.put("description", currentMode.getDescription()); status.put("running", pressureService.isRunning()); - status.put("bytesPerSecond", currentMode.getBytesPerSecond()); + status.put("allocationRateMBPerSec", currentMode.getAllocationRateMBPerSec()); + status.put("liveSetSizeMB", currentMode.getLiveSetSizeMB()); + status.put("scenarioType", currentMode.getScenarioType()); return Response.ok(status).build(); } @@ -65,8 +41,8 @@ public Response setMode(@PathParam("mode") String modeStr) { AllocationMode mode = AllocationMode.valueOf(modeStr.toUpperCase()); LOGGER.info( String.format( - "POST /api/pressure/mode/%s - Setting memory pressure mode to: %s (%.2f MB/sec)", - modeStr, mode.name(), mode.getBytesPerSecond() / (1024.0 * 1024.0))); + "POST /api/pressure/mode/%s - Setting memory pressure mode to: %s", + modeStr, mode.name())); pressureService.setAllocationMode(mode); @@ -74,7 +50,8 @@ public Response setMode(@PathParam("mode") String modeStr) { result.put("success", true); result.put("mode", mode.name()); result.put("description", mode.getDescription()); - result.put("bytesPerSecond", mode.getBytesPerSecond()); + result.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); + result.put("scenarioType", mode.getScenarioType()); return Response.ok(result).build(); } catch (IllegalArgumentException e) { @@ -83,53 +60,16 @@ public Response setMode(@PathParam("mode") String modeStr) { Map error = new HashMap<>(); error.put("success", false); error.put("error", "Invalid mode: " + modeStr); - error.put("validModes", new String[] {"OFF", "LOW", "MEDIUM", "HIGH", "EXTREME"}); + // Valid modes are all values of AllocationMode + StringBuilder validModes = new StringBuilder(); + for (AllocationMode m : AllocationMode.values()) { + validModes.append(m.name()).append(", "); + } + error.put("validModes", validModes.toString()); return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); } } - @POST - @Path("/scenario/{scenario}") - @Produces(MediaType.APPLICATION_JSON) - public Response applyScenario(@PathParam("scenario") String scenarioName) { - try { - StressScenario scenario = StressScenario.valueOf(scenarioName.toUpperCase()); - LOGGER.info("Applying scenario: " + scenario.name()); - - pressureService.setAllocationMode(scenario.getMode()); - - return Response.ok( - Map.of( - "scenario", scenario.name(), - "description", scenario.getDescription(), - "mode", scenario.getMode(), - "status", "applied")) - .build(); - - } catch (IllegalArgumentException e) { - return Response.status(Response.Status.BAD_REQUEST) - .entity(Map.of("error", "Invalid scenario: " + scenarioName)) - .build(); - } - } - - @GET - @Path("/scenarios") - @Produces(MediaType.APPLICATION_JSON) - public Response listScenarios() { - List> scenarios = - Arrays.stream(StressScenario.values()) - .map( - s -> - Map.of( - "name", s.name(), - "description", s.getDescription(), - "mode", s.getMode().toString())) - .collect(Collectors.toList()); - - return Response.ok(scenarios).build(); - } - @GET @Path("/modes") @Produces(MediaType.APPLICATION_JSON) @@ -142,7 +82,9 @@ public Response getModes() { Map modeInfo = new HashMap<>(); modeInfo.put("name", mode.name()); modeInfo.put("description", mode.getDescription()); - modeInfo.put("bytesPerSecond", mode.getBytesPerSecond()); + modeInfo.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); + modeInfo.put("liveSetSizeMB", mode.getLiveSetSizeMB()); + modeInfo.put("scenarioType", mode.getScenarioType()); modes.put(mode.name(), modeInfo); } diff --git a/src/main/webapp/blog.html b/src/main/webapp/blog.html index 383301e..da08d2b 100644 --- a/src/main/webapp/blog.html +++ b/src/main/webapp/blog.html @@ -293,19 +293,31 @@

Azul C4 and Payara: The Ideal Base for High-Speed Financial Applications

I developed TradeStreamEE, a sophisticated high-frequency trading dashboard to demonstrate that HFT is not only possible but also highly performant in Enterprise Java, particularly when combining Azul Platform Prime with the C4 garbage collector and Payara Micro. This technology stack changes Java's performance profile, offering measurable, real-world improvements that are now leading financial institutions to reconsider their current technology choices.

-

The Evidence: 2GB/s Pressure, 1ms Latency

+

The Evidence: Scenario-Based GC Stress Testing

-

We subjected TradeStreamEE to an extreme torture test: generating 2 Gigabytes of garbage per second while simultaneously processing market data.

+

Rather than applying generic high-allocation pressure, TradeStreamEE uses scenario-based testing that targets specific garbage collector weaknesses. Each scenario exposes fundamental algorithmic differences between G1 and C4.

-

In a standard OpenJDK environment using G1GC, this level of pressure typically results in "Stop-the-World" pauses lasting hundreds of milliseconds. The user interface freezes. Tickers jump. Traders lose money.

+

The test scenarios include:

-

With Azul C4, the results were staggering. We queried the live application status while it was under this 2GB/s bombardment. Here is the raw JSON returned from our Payara endpoints:

+
    +
  • STEADY_LOAD: 200 MB/sec allocation with 512 MB stable live set. Tests baseline young generation collection behavior.
  • +
  • GROWING_HEAP: 150 MB/sec with live set growing from 100 MB to 2 GB over 60 seconds. Tests mixed collection pause scaling.
  • +
  • PROMOTION_STORM: 300 MB/sec with 50% survival rate. Tests old generation collection efficiency under high promotion.
  • +
  • FRAGMENTATION: 200 MB/sec with small objects (100-1000 bytes). Tests compaction behavior.
  • +
  • CROSS_GEN_REFS: 150 MB/sec with 800 MB in old generation holding references to young objects. Tests remembered set overhead.
  • +
+ +

Each scenario uses 4 parallel threads to generate allocation load, mirroring production web servers and trading systems where multiple threads compete for heap space. The allocation rates (100-300 MB/sec) are calibrated to demonstrate normal GC behavior rather than pathological thrashing, ensuring consistent results across 2GB-4GB heap configurations.

+ +

Here is the raw JSON returned from our Payara endpoints during a PROMOTION_STORM scenario:

{
   "running": true,
-  "description": "2 GB/sec - Extreme pressure",
-  "bytesPerSecond": 2048000000,
-  "currentMode": "EXTREME",
+  "currentMode": "PROMOTION_STORM",
+  "description": "High promotion rate (50% survival) - Tests old gen collection efficiency",
+  "allocationRateMBPerSec": 300,
+  "liveSetSizeMB": 1024,
+  "scenarioType": "PROMOTION",
   "percentiles": {
     "max": 1,
     "p50": 0,
@@ -315,8 +327,8 @@ 

The Evidence: 2GB/s Pressure, 1ms Latency

}
-

Read that again.

-

Allocating 2GB of data every second, the application's garbage collection pauses peaked at 1 millisecond. The 50th percentile (median) was 0ms. The SLA monitor reported zero violations over 10ms.

+

The Results

+

Under PROMOTION_STORM (300 MB/sec with high old generation traffic), the application's garbage collection pauses peaked at 1 millisecond. The 50th percentile (median) was 0ms. G1 under the same scenario exhibited pauses of 50-200ms as mixed collections struggled to keep pace with promotion rates.

Payara Micro: Enterprise Jakarta EE for Demanding Applications

@@ -369,21 +381,35 @@

The "Hero": Zero-Copy SBE

final long quantity = tradeDecoder.quantity(); } -

The "Villain": The Memory Pressure Service

+

The "Villain": Scenario-Based Memory Pressure

+ +

To demonstrate collector behavior under specific pathological conditions, the MemoryPressureService implements five distinct scenarios. Each targets a known G1 weakness while C4 handles the workload without pause.

-

To prove the reliability of the system, we included a component designed specifically to break it. The MemoryPressureService generates massive amounts of random data to simulate extreme market volatility or memory leaks.

+

The CROSS_GEN_REFS scenario is particularly instructive. It creates old generation objects that hold references to newly allocated young objects, triggering G1's write barriers and remembered set maintenance:

-
// The "Villain": Generating 2GB/sec of garbage to stress the JVM
-private void generateGarbage(AllocationMode mode) {
-    // 20,000 allocations per 100ms iteration = ~2GB/sec
-    for (int i = 0; i < mode.getAllocationsPerIteration(); i++) {
-        // Create 100KB byte array, touch it, and immediately discard it
-        byte[] garbage = new byte[1024 * 100];
-        ThreadLocalRandom.current().nextBytes(garbage); // Prevent optimization
+            
// Cross-generational reference stress test
+private static class RefHolder {
+    volatile Object youngRef;  // Updated frequently to trigger write barriers
+    final byte[] padding;      // 1MB padding to establish old gen presence
+}
+
+private void createCrossGenerationalRefsMultiThreaded(int totalBytes, int numThreads) {
+    RefHolder[] holders = crossRefHolders.toArray(new RefHolder[0]);
+
+    for (int t = 0; t < numThreads; t++) {
+        futures[t] = CompletableFuture.runAsync(() -> {
+            int remaining = bytesPerThread;
+            while (remaining > 0) {
+                byte[] youngObj = new byte[size];
+                // This write triggers G1's post-write barrier
+                holders[idx].youngRef = youngObj;
+                remaining -= size;
+            }
+        }, executorService);
     }
 }
-

Even with this "villain" running full throttle, the Azul C4 collector cleaned up the mess concurrently, ensuring the trading threads never stopped.

+

G1 must track every old-to-young reference update via card tables and remembered sets. During young collection, G1 scans these remembered sets to find roots, adding overhead proportional to cross-reference volume. C4 has no generational boundaries, eliminating this overhead entirely.

The Business Impact

@@ -409,7 +435,7 @@

Ready to See It in Action?

  • Try Payara Micro: Download Payara Micro and experience the lightweight, enterprise-grade application server for yourself.
  • Try Payara Qube: Deploy to Payara Qube (formerly Payara Cloud) for effortless cloud deployment without the infrastructure overhead.
  • Evaluate Azul Platform Prime: Request a trial of Azul Platform Prime to see C4 garbage collection in action. The performance improvements are immediately noticeable, especially under memory pressure.
  • -
  • Run Your Own Tests: Use the built-in stress testing capabilities in TradeStreamEE to see how your applications perform under realistic load conditions.
  • +
  • Run Your Own Tests: Use the built-in scenario-based stress testing in TradeStreamEE. The five scenarios (STEADY_LOAD, GROWING_HEAP, PROMOTION_STORM, FRAGMENTATION, CROSS_GEN_REFS) target specific GC weaknesses, allowing direct comparison between G1 and C4 behavior under controlled conditions.
  • diff --git a/src/main/webapp/images/payara.png b/src/main/webapp/images/payara.png new file mode 100644 index 0000000000000000000000000000000000000000..a5554c033f1e9eaae127b17a229a036abfffd337 GIT binary patch literal 61920 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 z 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

    vHv&qxN#^KyXfV9WoB_ZWTnMufwD*;Zl#36 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

    WNqPAM1Z_>=69(r2AI|@EG+Z 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 C4 + Payara Micro for Low-Latency Trading

    + +
    +

    Part 1

    +

    The Problem

    +

    Why GC pauses matter in financial systems

    +
    +

    The Problem: GC Pauses in Financial Systems

    @@ -226,7 +233,7 @@

    Why Traditional Java Struggles with HFT

    The Challenge

      -
    • HFT processes millions of messages/second
    • +
    • HFT processes 50,000-100,000+ messages/second
    • Latency budgets measured in microseconds
    • Single 50ms pause = missed trades
    • Unpredictable latency violates SLAs
    • @@ -348,30 +355,31 @@

      Compaction Pauses

      -

      Azul C4: Concurrent by Design

      +

      Azul C4/GPGC: Concurrent by Design

      How Pauseless Collection Works

      -

      Read Barriers

      +

      Read Barriers (LVB)

        -
      • Check object state on every read
      • +
      • Loaded Value Barrier on every read
      • Relocate objects on-the-fly
      • -
      • No stop-the-world compaction
      • -
      • Hardware-assisted (LVB)
      • +
      • Enables concurrent compaction
      • +
      • Small overhead, huge benefit
      -

      No Generations

      +

      Concurrent Generations

        -
      • Single heap region
      • -
      • No remembered sets needed
      • -
      • No write barrier overhead
      • -
      • Simpler, more predictable
      • +
      • Has young (New) and old generations
      • +
      • Both collected concurrently
      • +
      • No STW for generational collection
      • +
      • No remembered set scanning pauses
      -

      Result: Pause times remain under 1ms regardless of heap size or live set.

      +

      Result: Sub-millisecond pauses regardless of heap size or live set.

      +

      C4 = algorithm name; GPGC (Generational Pauseless GC) = collector implementation in JMX

      @@ -453,6 +461,13 @@

      Testing G1's Write Barrier Overhead

    + +
    +

    Part 2

    +

    Architecture

    +

    Zero-copy pipeline design with Jakarta EE

    +
    +

    TradeStreamEE Architecture

    @@ -488,6 +503,88 @@

    Application Layer

    + +
    +

    Dual-Mode Ingestion

    +

    AERON vs DIRECT: Controlled Comparison

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AspectAERON ModeDIRECT Mode
    EncodingSBE binaryJSON strings
    TransportShared memory IPCIn-process calls
    Allocation~0 bytes/message~1KB+ per message
    GC PressureMinimalHigh (intentional)
    PurposeProduction patternGC stress baseline
    +
    +

    DIRECT mode adds 1KB+ padding per message to stress the garbage collector. This isolates GC as the variable when comparing C4 vs G1.

    +
    +
    + + +
    +

    SBE Schema: 5 Message Types

    +

    Defined in market-data.xml

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MessageIDKey Fields
    Trade1timestamp, tradeId, price, quantity, side, symbol
    Quote2timestamp, bidPrice, bidSize, askPrice, askSize, symbol
    MarketDepth3bids[], asks[] (5 levels), sequenceNumber
    OrderAck4orderId, execType, leavesQty, cumQty, side
    Heartbeat5timestamp, sequenceNumber
    +

    + Price encoding: int64 Γ— 10,000 for 4 decimal places. Little-endian byte order. +

    +
    +

    SBE: Zero-Copy Message Processing

    @@ -541,18 +638,61 @@

    Aeron IPC

  • Direct memory access
  • Zero-copy with SBE
  • No kernel involvement
  • -
  • Latency: sub-microsecond
  • +
  • Transport latency: sub-microsecond
  • Aeron's ring buffer in shared memory allows components on the same machine to communicate without network overhead. Combined with SBE, the entire path from publisher to subscriber involves no object allocation.

    +

    Note: End-to-end latency includes WebSocket broadcast and JSON conversion. Transport layer is sub-microsecond.

    +
    +
    + + +
    +

    Aeron Configuration Details

    +

    Production-Ready Settings

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterValuePurpose
    Channelaeron:ipcInter-process communication mode
    Stream ID1001Logical message stream identifier
    Fragment Limit10Messages polled per iteration
    Idle StrategyBackoffIdleStrategy100ns β†’ 100ΞΌs adaptive backoff
    Shared Memory512 MBIPC buffer size (Docker tmpfs)
    +
    +

    Circuit Breaker

    +

    Publisher stops after 50 consecutive offer failures to prevent resource exhaustion.

    -

    Payara Micro: Enterprise Runtime

    +

    Payara Micro 7.2025.2

    Jakarta EE 11 for Financial Applications

    @@ -569,10 +709,10 @@

    Features

    Clustering

      -
    • Hazelcast built-in
    • -
    • Automatic discovery
    • -
    • Distributed counters
    • -
    • Session replication
    • +
    • Hazelcast 5.5 built-in
    • +
    • TCP/IP discovery (Docker)
    • +
    • CP Subsystem for counters
    • +
    • Reliable Topics (back-pressure)
    • No external infrastructure
    @@ -593,8 +733,9 @@

    Clustering

    Jakarta Concurrency 3.1

    Virtual Threads for Memory Pressure Testing

    
    -@Resource
    -private ManagedExecutorService executorService;
    +@Inject
    +@VirtualThreadExecutor  // Jakarta Concurrency 3.1 - virtual threads
    +private ManagedExecutorService managedExecutorService;
     
     private void allocateTransientGarbageMultiThreaded(int totalBytes, int numThreads) {
         int bytesPerThread = totalBytes / numThreads;
    @@ -605,7 +746,7 @@ 

    Virtual Threads for Memory Pressure Testing

    byte[] garbage = new byte[bytesPerThread]; ThreadLocalRandom.current().nextBytes(garbage); totalBytesAllocated.addAndGet(bytesPerThread); - }, executorService); + }, managedExecutorService); } CompletableFuture.allOf(futures).join(); @@ -616,34 +757,53 @@

    Virtual Threads for Memory Pressure Testing

    + +
    +

    Part 3

    +

    Test Results

    +

    Measured GC behavior under stress scenarios

    +
    +

    Test Results: G1 vs C4

    Under PROMOTION_STORM (300 MB/sec, 50% survival)

    -
    50-200ms
    -
    G1 Mixed Collection Pauses
    +
    25ms
    +
    G1 Maximum Pause (measured)
    -
    < 1ms
    -
    C4 Maximum Pause
    +
    2ms
    +
    C4 Maximum Pause (measured)
    -
    
    +            
    +
    +

    G1GC (Zulu 21)

    +
    
     {
    -  "currentMode": "PROMOTION_STORM",
    -  "allocationRateMBPerSec": 300,
    -  "liveSetSizeMB": 1024,
    -  "percentiles": {
    -    "p50": 0,
    -    "p99": 1,
    -    "max": 1
    -  }
    +  "pauseP50Ms": 3, "pauseP95Ms": 16,
    +  "pauseP99Ms": 24, "pauseMaxMs": 25,
    +  "avgPauseMs": 4.87,
    +  "slaViolations10ms": 20
     }
    -            
    -

    - C4 maintains sub-millisecond pauses regardless of promotion rate or live set size. +

    + +
    +

    C4/GPGC (Prime 21)

    +
    
    +{
    +  "pauseP50Ms": 0, "pauseP95Ms": 1,
    +  "pauseP99Ms": 1, "pauseMaxMs": 2,
    +  "avgPauseMs": 0.078,
    +  "slaViolations10ms": 0
    +}
    +                    
    +
    + +

    + Same workload, same allocation rate. G1: 20 SLA violations | C4: Zero violations

    @@ -678,6 +838,102 @@

    C4 Behavior

    + +
    +

    Burst Pattern Simulation

    +

    Realistic Market Conditions

    +
    +

    The publisher simulates a 60-second market cycle:

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TimeEventRate Multiplier
    0-20sNormal trading1x
    20-25sNews event spike5x burst
    25-45sNormal trading1x
    45-50sMarket close rush3x spike
    50-60sNormal trading1x
    +

    + Tests GC response to variable load. G1 may trigger mixed collections during bursts; C4 adapts smoothly. +

    +
    + + +
    +

    SLA Violation Tracking

    +

    Real-Time Compliance Monitoring

    +
    +
    +

    Tracked Thresholds

    +
      +
    • < 10ms - Within SLA
    • +
    • > 10ms - Minor violation
    • +
    • > 50ms - Major violation
    • +
    • > 100ms - Critical violation
    • +
    +
    +
    +

    Metrics Collected

    +
      +
    • P50, P95, P99, P999 latency
    • +
    • All-time maximum pause
    • +
    • Total pause count and time
    • +
    • Violation counts by threshold
    • +
    +
    +
    +
    +
    +

    G1GC SLA Stats

    +
    
    +{
    +  "totalPauseCount": 164,
    +  "totalPauseTimeMs": 799,
    +  "violationsOver10ms": 20,
    +  "violationsOver50ms": 0,
    +  "violationsOver100ms": 0
    +}
    +                    
    +
    +
    +

    C4 SLA Stats

    +
    
    +{
    +  "totalPauseCount": 665,
    +  "totalPauseTimeMs": 52,
    +  "violationsOver10ms": 0,
    +  "violationsOver50ms": 0,
    +  "violationsOver100ms": 0
    +}
    +                    
    +
    +
    +
    +

    Business Impact

    @@ -708,7 +964,24 @@

    Cost of a 100ms Pause

    - + +
    +

    Part 4

    +

    Demo & Deployment

    +

    Running and monitoring the application

    +
    + + +
    +

    Live Dashboard

    +

    Real-Time GC Visualization

    + TradeStreamEE Dashboard +

    + WebSocket-connected dashboard showing live message rates, GC pause percentiles, and SLA violations. +

    +
    + +

    Deployment Options

    Running TradeStreamEE

    @@ -742,6 +1015,32 @@

    Comparison Stack

    + +
    +

    Comparison Stack Architecture

    +

    Side-by-Side C4 vs G1 Testing

    +
    
    +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    +β”‚   C4 Cluster (Prime)    β”‚    β”‚   G1 Cluster (Temurin)  β”‚
    +β”‚   └─ Traefik :8080      β”‚    β”‚   └─ Traefik :9080      β”‚
    +β”‚      β”œβ”€ instance-1      β”‚    β”‚      β”œβ”€ instance-1      β”‚
    +β”‚      β”œβ”€ instance-2      β”‚    β”‚      β”œβ”€ instance-2      β”‚
    +β”‚      └─ instance-3      β”‚    β”‚      └─ instance-3      β”‚
    +β”‚   JMX: 9010-9012        β”‚    β”‚   JMX: 9020-9022        β”‚
    +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    +            β”‚                              β”‚
    +            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    +                       β–Ό
    +              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    +              β”‚   Prometheus   │──▢ Grafana :3000
    +              β”‚    :9090       β”‚
    +              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    +            
    +

    + Both clusters run identical workloads. JMX Exporter exposes GC metrics to Prometheus. +

    +
    +

    Stress Testing API

    @@ -777,33 +1076,33 @@

    Technology Stack

    Runtime - Azul Platform Prime - C4 pauseless garbage collection + Azul Platform Prime 21 + C4/GPGC pauseless garbage collection App Server - Payara Micro 7 + Payara Micro 7.2025.2 Jakarta EE 11 container Transport - Aeron IPC - Shared memory messaging + Aeron 1.46.7 + Shared memory IPC messaging Encoding - SBE + SBE 1.34.0 Zero-copy binary serialization Clustering - Hazelcast - Distributed state and discovery + Hazelcast 5.5.0 + Distributed topics and CP subsystem Monitoring Prometheus + Grafana - Metrics and visualization + JMX metrics and visualization
    @@ -813,11 +1112,11 @@

    Technology Stack

    Key Takeaways

    1. G1's stop-the-world pauses are architectural - no tuning eliminates them
    2. -
    3. C4 collects concurrently - application never stops
    4. +
    5. C4/GPGC collects concurrently - application never stops
    6. Pause time in G1 scales with live set - larger heaps = longer pauses
    7. C4 pause time is constant - regardless of heap or live set size
    8. Remembered sets add overhead in G1 - cross-gen refs trigger write barriers
    9. -
    10. C4 has no generations - no remembered sets, no barrier overhead
    11. +
    12. C4 collects generations concurrently - no STW for generational collection
    13. Scenario-based testing exposes weaknesses - targeted stress reveals true behavior
    14. Enterprise Java can achieve HFT latency - with the right runtime
    @@ -829,12 +1128,12 @@

    Resources

    TradeStreamEE Features

      -
    • Scenario-based GC stress testing (5 scenarios)
    • +
    • Scenario-based GC stress testing (6 allocation modes)
    • Real-time pause time visualization
    • -
    • Side-by-side C4 vs G1 comparison
    • -
    • Zero-copy message pipeline (Aeron + SBE)
    • -
    • Hazelcast clustering support
    • -
    • Prometheus/Grafana monitoring
    • +
    • Side-by-side C4 vs G1 comparison clusters
    • +
    • Zero-copy message pipeline (Aeron 1.46.7 + SBE 1.34.0)
    • +
    • Hazelcast 5.5 clustering with reliable topics
    • +
    • Prometheus/Grafana monitoring stack

    Learn More

    @@ -846,6 +1145,35 @@

    Learn More

    + +
    +

    Lessons Learned

    +

    Practical Insights from Implementation

    +
    +
    +

    What Worked

    +
      +
    • SBE flyweight pattern eliminates allocation
    • +
    • Aeron IPC provides true zero-copy
    • +
    • C4 requires no tuning for consistent pauses
    • +
    • Scenario-based testing reveals real behavior
    • +
    +
    +
    +

    Watch Out For

    +
      +
    • GPGC reports as collector name, not "C4"
    • +
    • WebSocket JSON conversion adds latency
    • +
    • 1-in-50 sampling needed for UI stability
    • +
    • Docker shared memory sizing for Aeron
    • +
    +
    +
    +
    +

    Key Insight: The application code stays simple. The GC choice handles the complexity of memory management without code changes.

    +
    +
    +
    @@ -866,6 +1194,7 @@

    Questions?

    Reveal.initialize({ hash: true, slideNumber: true, + loop: true, transition: 'slide', backgroundTransition: 'fade', plugins: [RevealMarkdown, RevealHighlight, RevealNotes], From 343014621db18d075ee9d016396f30578579ff90 Mon Sep 17 00:00:00 2001 From: Luqman Saeed Date: Sat, 3 Jan 2026 19:35:22 +0000 Subject: [PATCH 6/6] Amend reame --- README.md | 83 ++++++++++++++++++++++----------------- src/main/webapp/blog.html | 60 ++++++++++++++-------------- 2 files changed, 76 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index fa3a37f..0d0b268 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # TradeStreamEE: High-Frequency Trading Reference Architecture -TradeStreamEE demonstrates how Jakarta EE applications can achieve low-latency, high-throughput performance by combining modern messaging (Aeron), efficient serialization (SBE), and a concurrent garbage collector like Azul C4. +TradeStreamEE shows how Jakarta EE applications can achieve low-latency, high-throughput performance by combining modern messaging (Aeron), efficient serialization (SBE), and a concurrent garbage collector like Azul C4. -The application simulates a high-frequency trading dashboard that ingests tens of thousands of market data messages per second, processes them in real-time, and broadcasts updates to a web frontend without the latency spikes associated with traditional Java garbage collection. +The application simulates a high-frequency trading dashboard that ingests 30,000-100,000 market data messages per second, processes them in real-time, and broadcasts updates to a web frontend without the latency spikes associated with traditional Java garbage collection. ## Core Technologies @@ -16,13 +16,13 @@ Ultra-low latency messaging that bypasses the network stack when components run Simple Binary Encoding is the financial industry standard for high-frequency trading. Encodes data as compact binary rather than human-readable text, eliminating parsing overhead and reducing memory allocation. -### Payara Micro (Jakarta EE Runtime) +### Payara Micro 7.2025.2 (Jakarta EE Runtime) A cloud-native Jakarta EE 11 application server that provides Jakarta CDI for dependency injection, Jakarta WebSocket for real-time browser communication, and Jakarta REST for REST endpoints. Lightweight (~100MB) and fast-starting. -### Azul Platform Prime (Runtime) +### Azul Platform Prime 21 (Runtime) -A JVM with the C4 garbage collector that performs cleanup concurrently with application execution, avoiding the stop-the-world pauses that cause latency spikes in traditional JVMs. +A JVM with the C4 (Continuously Concurrent Compacting Collector) garbage collector. C4 performs cleanup concurrently with application execution, avoiding the stop-the-world pauses that cause latency spikes in traditional JVMs. Azul markets C4 as a "pauseless" collector due to its sub-millisecond pause times across all heap sizes. Integration: Payara Micro manages the Aeron publisher/subscriber lifecycle via CDI. The publisher encodes market data into binary using SBE, sends it through Aeron's shared memory transport, and the subscriber decodes it without allocating Java objects. This minimal garbage generation allows C4's concurrent collection to handle cleanup while maintaining flat latency at high throughput. @@ -33,7 +33,8 @@ Enterprise Java applications must often balance two competing requirements: 1. High Throughput: Ingesting massive data streams (IoT, Financial Data). 2. Low Latency: Processing data without stop-the-world pauses. -Standard JVMs (using G1GC or ParallelGC) can exhibit latency spikes under high load, potentially causing UI freezes or missed SLAs. TradeStreamEE demonstrates that by combining a modern, broker-less transport (Aeron) with a pauseless runtime (Azul C4), standard Jakarta EE applications can achieve microsecond-level latency and high throughput. +Standard JVMs (using G1GC or ParallelGC) exhibit latency spikes under high load, potentially causing UI freezes or missed SLAs. +TradeStreamEE shows that through combining a modern, broker-less transport (Aeron) with a concurrent runtime (Azul C4), standard Jakarta EE applications can achieve microsecond-level latency and high throughput. ### Comparison Methodology @@ -49,7 +50,9 @@ This isolation ensures that observed performance differences are attributable so ### Primary Use Case: Side-by-Side JVM Comparison -TradeStreamEE enables side-by-side JVM comparison by deploying both clusters simultaneously under identical workloads. Both clusters execute the same application binary and configuration, isolating the garbage collector as the sole variable. This approach allows for real-time observation of performance differences in a shared environment, providing a more objective comparison than traditional serial benchmarking. +TradeStreamEE enables side-by-side JVM comparison by deploying both clusters simultaneously under identical workloads. +Both clusters execute the same application binary and configuration, isolating the garbage collector as the sole variable. +This approach allows for real-time observation of performance differences in a shared environment. ```bash ./start-comparison.sh all @@ -62,7 +65,7 @@ Once deployed, access the applications: - C4 Cluster: http://localhost:8080/trader-stream-ee/ - G1 Cluster: http://localhost:9080/trader-stream-ee/ -The "GC Pause Time (Live)" chart in Grafana will demonstrate the performance characteristics: C4 typically maintains a consistent latency profile, while G1GC may exhibit spikes and sawtooth patterns under load. +The "GC Pause Time (Live)" chart in Grafana shows the performance characteristics: C4 maintains consistent latency (≀1ms pauses), while G1GC exhibits spikes and sawtooth patterns under load. Other options: @@ -75,12 +78,12 @@ Other options: Use `./start.sh` for testing individual configurations or architectural modes. This runs ONE JVM at a time for focused testing. -| Scenario | Command | JVM | Architecture | Purpose | -|:-------------------------|:-----------------------------|:--------------------|:------------------|:-----------------------------------------------------------------| -| Modern Stack | `./start.sh azul-aeron` | Azul Prime (C4) | Aeron (Optimized) | Peak performance with pauseless GC + zero-copy transport | -| Legacy Baseline | `./start.sh standard-direct` | Standard JDK (G1GC) | Direct (Heavy) | Baseline: high allocation on G1GC, expect jitter | -| Fixing Legacy Code | `./start.sh azul-direct` | Azul Prime (C4) | Direct (Heavy) | Show how C4 stabilizes high-allocation apps without code changes | -| Optimizing Standard Java | `./start.sh standard-aeron` | Standard JDK (G1GC) | Aeron (Optimized) | Test if architectural optimization helps G1GC performance | +| Scenario | Command | JVM | Architecture | Purpose | +|:-------------------------|:-----------------------------|:-----------------------|:------------------|:-----------------------------------------------------------------| +| Modern Stack | `./start.sh azul-aeron` | Azul Prime (C4) | Aeron (Optimized) | Peak performance with concurrent GC + zero-copy transport | +| Legacy Baseline | `./start.sh standard-direct` | Eclipse Temurin (G1GC) | Direct (Heavy) | Baseline: high allocation on G1GC, expect jitter | +| Fixing Legacy Code | `./start.sh azul-direct` | Azul Prime (C4) | Direct (Heavy) | Show how C4 stabilizes high-allocation apps without code changes | +| Optimizing Standard Java | `./start.sh standard-aeron` | Eclipse Temurin (G1GC) | Aeron (Optimized) | Test if architectural optimization helps G1GC performance | Utilities: @@ -101,21 +104,21 @@ The application implements a Hybrid Architecture: 3. Application Layer (Jakarta EE 11): * Payara Micro 7 serves as the container. * CDI manages the lifecycle of the Aeron Publisher and Subscriber. - * Jakarta Concurrency 3.1 leverages Virtual Threads for high-throughput memory pressure simulation. + * Jakarta Concurrency 3.1 uses Virtual Threads for high-throughput memory pressure simulation. * WebSockets push updates to the browser. 4. Runtime Layer: - * Azul Platform Prime uses the C4 Collector to clean up the "garbage" created by the WebSocket layer concurrently, ensuring a flat latency profile. + * Azul Platform Prime uses the C4 Collector to clean up garbage created by the WebSocket layer concurrently, ensuring a flat latency profile. ## Tech Stack -| Component | Technology | Role | -|:-----------|:------------------------------------|:----------------------------------------| -| Runtime | Azul Platform Prime (Zulu Prime 21) | The Pauseless JVM engine. | -| App Server | Payara Micro 7 (Jakarta EE 11) | Cloud-native Jakarta EE runtime. | -| Transport | Aeron | Low-latency, high-throughput messaging. | -| Encoding | SBE (Simple Binary Encoding) | Binary serialization (FIX standard). | -| Frontend | HTML5 / Chart.js | Real-time visualization via WebSockets. | -| Build | Docker / Maven | Containerized deployment. | +| Component | Technology | Role | +|:-----------|:--------------------------------------|:------------------------------------------| +| Runtime | Azul Platform Prime 21 | Concurrent JVM with C4 garbage collector. | +| App Server | Payara Micro 7.2025.2 (Jakarta EE 11) | Cloud-native Jakarta EE runtime. | +| Transport | Aeron | Low-latency, high-throughput messaging. | +| Encoding | SBE (Simple Binary Encoding) | Binary serialization (FIX standard). | +| Frontend | HTML5 / Chart.js | Real-time visualization via WebSockets. | +| Build | Docker / Maven | Containerized deployment. | ## Ingestion Architectures @@ -161,7 +164,7 @@ Implementation: Performance Characteristics: - High Allocation: Gigabytes of temporary String objects per second -- GC Pressure: Frequent pauses on G1GC; C4's concurrent collection avoids stop-the-world pauses but still performs work +- GC Pressure: Frequent pauses on G1GC; C4's concurrent collection maintains sub-millisecond pauses ### AERON Mode (Optimized Path, Default) @@ -180,9 +183,9 @@ Implementation: Performance Characteristics: -- Low Allocation: Almost no garbage in the ingestion hot-path +- Low Allocation: Minimal garbage in the ingestion hot-path - High Throughput: Aeron IPC handles millions of messages/sec with sub-microsecond latency -- Both JVMs benefit from reduced allocation, but C4 maintains flat latency profile +- Both JVMs benefit from reduced allocation; C4 maintains consistent latency profile ## Configuration & Tuning @@ -221,11 +224,11 @@ Infrastructure improvements: - GC Logging: Detailed event logging with decorators for analysis - Rate-Limited Logging: Prevents log flooding during high-throughput operations -Note: Azul Platform Prime uses C4 by default; we don't specify `-XX:+UseZGC` since C4 is the native, optimized collector for Azul Prime. +Note: Azul Platform Prime uses C4 by default; we don't specify `-XX:+UseG1GC` since C4 is the native, optimized collector for Azul Prime. ### GC Monitoring & Stress Testing -The application includes comprehensive GC monitoring and memory pressure testing capabilities to demonstrate JVM performance differences: +The application includes comprehensive GC monitoring and memory pressure testing capabilities to show JVM performance differences: #### GC Statistics Collection @@ -261,9 +264,9 @@ Test Scenarios: Expected Behavior: * G1: Stop-the-world pauses that scale with live set size, remembered set scanning overhead, compaction pauses under fragmentation -* C4: Zero pauses across all scenarios due to concurrent collection, no remembered sets, concurrent compaction +* C4: Pauses ≀1ms across all scenarios due to concurrent collection, no remembered sets, concurrent compaction -Each scenario uses 4 parallel virtual threads to generate allocation load. This multi-threaded pattern demonstrates G1's stop-the-world impact when all application threads must pause simultaneously. +Each scenario uses 4 parallel virtual threads to generate allocation load. This multi-threaded pattern shows G1's stop-the-world impact when all application threads must pause simultaneously. #### GC Scenario Control @@ -274,7 +277,7 @@ The web UI includes scenario selection controls that allow: * Side-by-side pause time visualization with phase breakdown * Observation of collector behavior under specific pathological conditions -This feature enables targeted demonstration of G1's architectural limitations versus C4's concurrent collection model. +This feature enables targeted observation of G1's architectural limitations versus C4's concurrent collection model. ## Monitoring & Observability @@ -387,8 +390,8 @@ Working Tests (170/170 passing): Coverage Metrics: - Tests: 170 unit tests with 100% pass rate -- Monitoring Coverage: >90% (SLAMonitor, GCStatsService) -- REST API Coverage: >85% (Resources and DTOs) +- Monitoring Coverage: β‰₯90% (SLAMonitor, GCStatsService) +- REST API Coverage: β‰₯85% (Resources and DTOs) - Instruction Coverage: High coverage for business logic; integration logic relies on `test.sh`. ### Test Categories @@ -418,6 +421,7 @@ For readers unfamiliar with high-frequency trading concepts, this glossary expla | Price Ladder | The hierarchical structure of bid and ask prices in an order book. Bid prices decrease as you move away from the best bid; ask prices increase as you move away from the best ask. | | Crossed Market | An abnormal market condition where the best bid price is higher than the best ask price. This should never occur in normal trading and indicates a data error or system malfunction. | | Flash Crash | A sudden, severe market downturn followed by rapid recovery, often triggered by algorithmic trading systems. The 2010 Flash Crash saw the Dow Jones drop nearly 1,000 points in minutes. These events create extreme allocation bursts as systems process massive order flow. | +| SLA (Service Level Agreement) | Performance guarantees, such as "99.9% of trades execute within 5ms". GC pauses can cause SLA violations if they exceed latency budgets. | ### Memory & Performance @@ -469,8 +473,15 @@ For readers unfamiliar with high-frequency trading concepts, this glossary expla | Ingestion Pipeline / Ingestion Layer | The component responsible for receiving and processing incoming market data feeds. Must handle extreme throughput (millions of messages/sec) with minimal latency. | | Hot Path / Critical Path | The code execution path that runs most frequently and must be highly optimized. In HFT, the ingestion and order routing paths are hot paths where even nanoseconds matter. | | Market Event | Significant market occurrences that trigger increased trading activity: market open/close, economic announcements, earnings releases, or sudden price movements. | -| SLA (Service Level Agreement) | Performance guarantees, such as "99.9% of trades execute within 5ms". GC pauses can cause SLA violations if they exceed latency budgets. | + +## References + +- [Azul C4 Garbage Collection Documentation](https://docs.azul.com/prime/c4-garbage-collection.html) +- [Azul Platform Prime Product Page](https://www.azul.com/products/components/pgc/) +- [Explanation of Azul's "Pauseless" Garbage Collector](https://stackoverflow.com/questions/4491260/explanation-of-azuls-pauseless-garbage-collector) +- [What To Expect When Evaluating Azul Platform Prime](https://docs.azul.com/prime/what-to-expect) +- [Apache Kafka Performance on Azul Platform Prime vs Vanilla OpenJDK](https://www.azul.com/blog/apache-kafka-performance-on-azul-platform-prime-vs-vanilla-openjdk/) ## License -This project is a reference implementation provided for demonstration purposes. +This project is a reference implementation showing low-latency Java techniques for educational purposes. diff --git a/src/main/webapp/blog.html b/src/main/webapp/blog.html index da08d2b..52fcf2e 100644 --- a/src/main/webapp/blog.html +++ b/src/main/webapp/blog.html @@ -287,15 +287,13 @@

    Azul C4 and Payara: The Ideal Base for High-Speed Financial Applications

    -

    In high-frequency trading (HFT) and financial services, every microsecond counts. The difference between profit and loss often comes down to how quickly your system can process market data and execute trades. For years, Java has been viewed with skepticism in the world of low-latency finance, primarily due to its notorious "stop-the-world" garbage collection pauses that can wreck predictable performance.

    +

    In high-frequency trading (HFT) and financial services, latency determines profitability. The difference between profit and loss comes down to how quickly your system can process market data and execute trades. For years, Java has been viewed with skepticism in low-latency finance, primarily due to its "stop-the-world" garbage collection pauses that can wreck predictable performance.

    -

    But what if I told you that Java is now one of the best choices for latency-sensitive financial applications?

    - -

    I developed TradeStreamEE, a sophisticated high-frequency trading dashboard to demonstrate that HFT is not only possible but also highly performant in Enterprise Java, particularly when combining Azul Platform Prime with the C4 garbage collector and Payara Micro. This technology stack changes Java's performance profile, offering measurable, real-world improvements that are now leading financial institutions to reconsider their current technology choices.

    +

    Java is now a viable platform for latency-sensitive financial applications. TradeStreamEE, a high-frequency trading reference architecture, shows HFT-class performance on Enterprise Java by combining Azul Platform Prime with the C4 garbage collector and Payara Micro. This technology stack changes Java's performance profile, offering measurable improvements that make Enterprise Java competitive for low-latency workloads.

    The Evidence: Scenario-Based GC Stress Testing

    -

    Rather than applying generic high-allocation pressure, TradeStreamEE uses scenario-based testing that targets specific garbage collector weaknesses. Each scenario exposes fundamental algorithmic differences between G1 and C4.

    +

    TradeStreamEE uses scenario-based testing that targets specific garbage collector weaknesses rather than applying generic high-allocation pressure. Each scenario exposes fundamental algorithmic differences between G1 and C4.

    The test scenarios include:

    @@ -307,7 +305,7 @@

    The Evidence: Scenario-Based GC Stress Testing

  • CROSS_GEN_REFS: 150 MB/sec with 800 MB in old generation holding references to young objects. Tests remembered set overhead.
  • -

    Each scenario uses 4 parallel threads to generate allocation load, mirroring production web servers and trading systems where multiple threads compete for heap space. The allocation rates (100-300 MB/sec) are calibrated to demonstrate normal GC behavior rather than pathological thrashing, ensuring consistent results across 2GB-4GB heap configurations.

    +

    Each scenario uses 4 parallel threads to generate allocation load, mirroring production web servers and trading systems where multiple threads compete for heap space. The allocation rates (100-300 MB/sec) are calibrated to show normal GC behavior rather than pathological thrashing, ensuring consistent results across 2GB-4GB heap configurations.

    Here is the raw JSON returned from our Payara endpoints during a PROMOTION_STORM scenario:

    @@ -328,20 +326,20 @@

    The Evidence: Scenario-Based GC Stress Testing

    The Results

    -

    Under PROMOTION_STORM (300 MB/sec with high old generation traffic), the application's garbage collection pauses peaked at 1 millisecond. The 50th percentile (median) was 0ms. G1 under the same scenario exhibited pauses of 50-200ms as mixed collections struggled to keep pace with promotion rates.

    +

    Under PROMOTION_STORM (300 MB/sec with high old generation traffic), the application's garbage collection pauses peaked at 1 millisecond. The 50th percentile (median) was 0ms. In comparable testing, G1 showed significantly higher pause times as mixed collections struggled to keep pace with promotion rates.

    Payara Micro: Enterprise Jakarta EE for Demanding Applications

    -

    While Azul C4 eliminates Java's performance limitations, Payara Micro provides the enterprise-grade Jakarta EE runtime that makes sophisticated financial applications possible.

    +

    While Azul C4 addresses Java's GC limitations, Payara Micro provides the enterprise-grade Jakarta EE runtime that enables sophisticated financial applications.

    -

    What makes Payara Micro well suited for financial services is its thoughtful balance of enterprise features and performance optimization. The platform weighs just 100MB and starts in seconds, making it perfect for the microservices architectures that dominate modern financial technology stacks. But do not be deceived by the small footprint. It packs the full power of Jakarta EE 11, featuring critical implementations like Jakarta CDI for dependency injection, WebSocket support for real-time communication, and Jakarta REST for RESTful APIs.

    +

    Payara Micro balances enterprise features with performance optimization. The runtime weighs approximately 100MB and starts in seconds, making it suitable for the microservices architectures common in modern financial technology stacks. Despite the small footprint, it provides the full capabilities of Jakarta EE 11, including Jakarta CDI for dependency injection, WebSocket support for real-time communication, and Jakarta REST for RESTful APIs.

    Built-in Clustering with Hazelcast

    -

    Using Hazelcast under the hood, Payara provides automatic data replication across cluster nodes. Through such deep integration, creating a cluster of Payara Micro instances is a breeze.

    +

    Using Hazelcast under the hood, Payara provides automatic data replication across cluster nodes. Through this integration, creating a cluster of Payara Micro instances requires minimal configuration.

    -

    In our code, we didn't have to write complex distributed consensus logic. We simply injected the Hazelcast instance to track global throughput across the cluster:

    +

    In our code, we injected the Hazelcast instance to track global throughput across the cluster without writing distributed consensus logic:

    // Payara + Hazelcast: Instant cluster-wide metrics without complex setup
     @Inject private HazelcastInstance hazelcastInstance;
    @@ -353,15 +351,15 @@ 

    Built-in Clustering with Hazelcast

    hazelcastInstance.getCPSubsystem().getAtomicLong("cluster-message-count"); }
    -

    This means financial firms can build highly available trading systems that can withstand node failures without losing market data or transaction state.

    +

    Financial firms can build highly available trading systems that withstand node failures without losing market data or transaction state.

    -

    Architecture Deep Dive Into TradeStreamEE

    +

    Architecture Deep Dive: TradeStreamEE

    -

    The TradeStreamEE application serves as a perfect showcase for what's possible when you combine Azul C4 and Payara Micro. The architecture demonstrates thoughtful engineering that addresses the specific challenges of financial trading systems.

    +

    The TradeStreamEE application shows what is possible when you combine Azul C4 and Payara Micro. The architecture addresses the specific challenges of financial trading systems.

    -

    The "Hero": Zero-Copy SBE

    +

    Core Technology: Zero-Copy SBE

    -

    At the core of the system is Aeron IPC with Simple Binary Encoding (SBE), technologies that enable zero-copy message processing. The approach is elegant: instead of creating new Java objects for every market data message, the system uses "flyweight" objects that act as windows over shared memory buffers. This eliminates object allocation entirely during the critical path of message processing.

    +

    At the core of the system is Aeron IPC with Simple Binary Encoding (SBE), technologies that enable zero-copy message processing. Instead of creating new Java objects for every market data message, the system uses "flyweight" objects that act as views over shared memory buffers. This eliminates object allocation during the critical path of message processing.

    // SBE Flyweight pattern - zero object allocation during processing
     private final TradeDecoder tradeDecoder = new TradeDecoder();
    @@ -371,7 +369,7 @@ 

    The "Hero": Zero-Copy SBE

    public void onFragment(DirectBuffer buffer, int offset, int length, Header header) { headerDecoder.wrap(buffer, offset); - // Move the "window" to the data without allocating a new object + // Move the "view" to the data without allocating a new object tradeDecoder.wrap(buffer, offset + headerDecoder.encodedLength(), headerDecoder.blockLength(), headerDecoder.version()); @@ -381,11 +379,11 @@

    The "Hero": Zero-Copy SBE

    final long quantity = tradeDecoder.quantity(); }
    -

    The "Villain": Scenario-Based Memory Pressure

    +

    Stress Testing: Scenario-Based Memory Pressure

    -

    To demonstrate collector behavior under specific pathological conditions, the MemoryPressureService implements five distinct scenarios. Each targets a known G1 weakness while C4 handles the workload without pause.

    +

    To show collector behavior under specific pathological conditions, the MemoryPressureService implements five distinct scenarios. Each targets a known G1 weakness while C4 handles the workload without pause.

    -

    The CROSS_GEN_REFS scenario is particularly instructive. It creates old generation objects that hold references to newly allocated young objects, triggering G1's write barriers and remembered set maintenance:

    +

    The CROSS_GEN_REFS scenario creates old generation objects that hold references to newly allocated young objects, triggering G1's write barriers and remembered set maintenance:

    // Cross-generational reference stress test
     private static class RefHolder {
    @@ -413,28 +411,28 @@ 

    The "Villain": Scenario-Based Memory Pressure

    The Business Impact

    -

    The business implications of this technology combination extend far beyond technical performance metrics. For trading firms, predictable latency directly translates to competitive advantage in the market.

    +

    The business implications of this technology combination extend beyond technical performance metrics. For trading firms, predictable latency directly translates to competitive advantage in the market.

    -

    Perhaps more importantly, the operational complexity that has traditionally plagued Java performance tuning virtually disappears. The standard approach to Java latency problems involved teams of performance engineers spending months tuning JVM parameters (-XX:NewRatio, -XX:SurvivorRatio). With Azul C4 and Payara Micro, most of that complexity evaporates. C4 adapts automatically to workload patterns, eliminating the need for manual parameter tuning.

    +

    Operational complexity also decreases significantly. Traditional Java performance tuning often requires considerable effort to optimize JVM parameters (-XX:NewRatio, -XX:SurvivorRatio). With Azul C4 and Payara Micro, C4 adapts automatically to workload patterns, eliminating the need for manual parameter tuning.

    -

    In our tests, a single Payara Micro instance effortlessly handled ingestion rates exceeding 30 million messages, with zero degradation in SLA compliance. This means financial firms can process more trades per second, handle higher client volumes without performance degradation, and maintain consistent service levels even during market stress events.

    +

    In our tests, a single Payara Micro instance handled sustained ingestion at rates exceeding 30,000 messages per second with zero GC pauses exceeding 1ms. Financial firms can process more trades per second, handle higher client volumes without performance degradation, and maintain consistent service levels during market stress events.

    Conclusion

    -

    Azul C4 and Payara Micro fundamentally redefine the potential of Java for low-latency financial applications. This is more than an incremental gain; it's a paradigm shift.

    +

    Azul C4 and Payara Micro redefine the capabilities of Java for low-latency financial applications. This represents a fundamental shift in what is possible with Enterprise Java.

    -

    By combining the operational maturity of Payara with the runtime supremacy of Azul Platform Prime, organizations can have their cake and eat it too. You can build maintainable, secure, and scalable Jakarta EE applications that meet the most demanding latency SLAs of the financial industry.

    +

    By combining the operational maturity of Payara with the superior runtime performance of Azul Platform Prime, organizations can achieve both development productivity and runtime performance. You can build maintainable, secure, and scalable Jakarta EE applications that meet the strict latency SLAs required by financial trading systems.

    -

    The question is no longer whether Java can handle low-latency financial workloads. With Azul C4 and Payara, it's now one of the best choices available.

    +

    Java can handle low-latency financial workloads. With Azul C4 and Payara, it is a competitive choice.

    Ready to See It in Action?

    -

    The theory is compelling, but the real proof is in the running system. I encourage you to:

    +

    The theory is compelling, but the real proof is in the running system. Explore the following:

      -
    • Explore the Code: Check out the TradeStreamEE repository on GitHub to see the complete implementation. The codebase demos best practices for low-latency Java development.
    • -
    • Try Payara Micro: Download Payara Micro and experience the lightweight, enterprise-grade application server for yourself.
    • -
    • Try Payara Qube: Deploy to Payara Qube (formerly Payara Cloud) for effortless cloud deployment without the infrastructure overhead.
    • -
    • Evaluate Azul Platform Prime: Request a trial of Azul Platform Prime to see C4 garbage collection in action. The performance improvements are immediately noticeable, especially under memory pressure.
    • +
    • Explore the Code: Check out the TradeStreamEE repository on GitHub to see the complete implementation. The codebase shows best practices for low-latency Java development.
    • +
    • Try Payara Micro: Download Payara Micro and experience the lightweight, enterprise-grade application server.
    • +
    • Try Payara Qube: Deploy to Payara Qube (formerly Payara Cloud) for cloud deployment without infrastructure overhead.
    • +
    • Evaluate Azul Platform Prime: Request a trial of Azul Platform Prime to see C4 garbage collection in action. The performance improvements are noticeable under memory pressure.
    • Run Your Own Tests: Use the built-in scenario-based stress testing in TradeStreamEE. The five scenarios (STEADY_LOAD, GROWING_HEAP, PROMOTION_STORM, FRAGMENTATION, CROSS_GEN_REFS) target specific GC weaknesses, allowing direct comparison between G1 and C4 behavior under controlled conditions.

    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
    -

    Demo Scenarios

    +

    Test Scenarios

    - - - - + + + +
    @@ -1130,49 +1140,45 @@

    GC Statistics

    - GC Challenge Mode + GC Scenario Control OFF Click to learn
    -
    Allocation Rate
    +
    Allocation Rate
    0 MB/sec
    -
    HFT Pattern
    +
    Active Scenario
    - OrderBook β†’ MarketTick β†’ MarketDepth + None
    - - - - - + + + +
    -

    GC Challenge Mode

    -

    Uses realistic HFT allocation patterns to stress-test the GC. Rotates through OrderBook, MarketTick, and MarketDepth patterns that match actual trading system memory profiles.

    -

    Azul C4: Maintains low, consistent pause times even under EXTREME allocation - pressure with coordinated bursts. Concurrent collection keeps up.

    -

    G1GC: Pause times spike as allocation rate increases. Bursts cause severe stuttering in - message delivery and chart updates.

    -

    Rates: LOW=2MB/s, MEDIUM=20MB/s, HIGH=1GB/s, EXTREME=4GB/s

    -

    Bursts: All active modes include 3x allocation bursts every 5 seconds to simulate flash crashes and market events.

    +

    GC Stress Scenarios

    +

    Select a scenario to target specific GC weaknesses:

    +

    Steady Load: Baseline 200MB/s. Tests young gen collection latency.

    +

    Growing Heap: Fills live set to 2GB. Tests mixed/major collection behavior as heap fills.

    +

    Promotion Storm: High survival rate. Floods old generation to force expensive collections.

    +

    Fragmentation: (Via Top Bar) Creates Swiss-cheese heap to force compaction pauses.

    - Patterns: OrderBook (5KB), MarketTick (4KB), MarketDepth (6KB)
    - Burst Multiplier: 3x every 5 seconds (all modes except OFF) + Goal: Compare G1 vs C4 latency under specific pathological conditions.
    + C4 Advantage: Should remain pauseless in all scenarios.
    @@ -1537,9 +1543,11 @@

    System Log

    const buttons = document.querySelectorAll('[onclick*="setPressureMode"]'); let clickedButton = null; buttons.forEach(btn => { - if (btn.textContent.trim() === mode) { - clickedButton = btn; - btn.classList.add('processing'); + // Simple check to find the button that was clicked if possible, + // or we highlight based on mode in pollPressureStatus + if (btn.textContent.includes(mode) || btn.id === 'btn-' + mode) { + btn.classList.add('processing'); + clickedButton = btn; } }); @@ -1553,10 +1561,10 @@

    System Log

    clickedButton.classList.remove('processing'); } if (result.success) { - addLog('Memory pressure mode set to: ' + mode); + addLog('Scenario set to: ' + mode); pollPressureStatus(); } else { - addLog('Error setting pressure mode: ' + result.error); + addLog('Error setting scenario: ' + result.error); } }) .catch(error => { @@ -1564,12 +1572,10 @@

    System Log

    clickedButton.classList.remove('processing'); } console.error('Error setting pressure mode:', error); - addLog('Failed to set pressure mode: ' + error.message); + addLog('Failed to set mode: ' + error.message); }); } - let burstAnimationInterval = null; - function pollPressureStatus() { fetch(API_BASE + '/pressure/status') .then(response => { @@ -1579,28 +1585,23 @@

    System Log

    .then(status => { const mode = status.currentMode || 'OFF'; document.getElementById('pressureMode').textContent = mode; - const bytesPerSecond = status.bytesPerSecond ?? 0; - const rateMBps = isFinite(bytesPerSecond) ? (bytesPerSecond / (1024 * 1024)).toFixed(1) : '0'; + + const rateMBps = status.allocationRateMBPerSec || 0; document.getElementById('pressureRate').textContent = rateMBps + ' MB/sec'; + + const patternEl = document.getElementById('hftPattern'); + if (patternEl) { + patternEl.textContent = status.description || 'None'; + patternEl.title = status.description || ''; + } - // Show burst indicator for all active modes (except OFF) - const burstIndicator = document.getElementById('burstIndicator'); - if (mode !== 'OFF') { - if (!burstAnimationInterval) { - burstAnimationInterval = setInterval(() => { - burstIndicator.style.display = 'inline'; - setTimeout(() => { - burstIndicator.style.display = 'none'; - }, 1000); - }, 5000); + // Update active state of top buttons + document.querySelectorAll('.scenario-btn').forEach(btn => { + btn.classList.remove('active'); + if (btn.id === 'btn-' + mode) { + btn.classList.add('active'); } - } else { - if (burstAnimationInterval) { - clearInterval(burstAnimationInterval); - burstAnimationInterval = null; - } - burstIndicator.style.display = 'none'; - } + }); }) .catch(error => console.error('Error fetching pressure status:', error)); } @@ -1828,28 +1829,7 @@

    System Log

    }); } - async function applyScenario(scenario) { - document.querySelectorAll('.scenario-btn').forEach(btn => btn.classList.remove('active')); - - const btn = document.getElementById('btn-' + scenario); - if (btn) btn.classList.add('active'); - try { - const response = await fetch(API_BASE + '/pressure/scenario/' + scenario, { - method: 'POST' - }); - if (!response.ok) throw new Error(`HTTP ${response.status}`); - const result = await response.json(); - console.log('Applied scenario:', result); - - pollPressureStatus(); - - addLog('Scenario applied: ' + result.description); - } catch (error) { - console.error('Error applying scenario:', error); - addLog('Failed to apply scenario: ' + error.message); - } - } async function pollGCComparison() { try { diff --git a/src/main/webapp/presentation.html b/src/main/webapp/presentation.html new file mode 100644 index 0000000..a1e1413 --- /dev/null +++ b/src/main/webapp/presentation.html @@ -0,0 +1,880 @@ + + + + + + Pauseless Java for Financial Systems: Azul C4 + Payara Micro + + + + + + + +
    +
    + +
    + +

    Pauseless Java for Financial Systems

    +

    Azul C4 + Payara Micro for Low-Latency Trading

    +

    + TradeStreamEE
    + A Reference Architecture for High-Frequency Trading +

    +
    + + +
    +

    The Problem: GC Pauses in Financial Systems

    +

    Why Traditional Java Struggles with HFT

    +
    +
    +

    The Challenge

    +
      +
    • HFT processes millions of messages/second
    • +
    • Latency budgets measured in microseconds
    • +
    • Single 50ms pause = missed trades
    • +
    • Unpredictable latency violates SLAs
    • +
    +
    +
    +

    The Cause

    +
      +
    • G1 uses stop-the-world pauses
    • +
    • All application threads halt during GC
    • +
    • Pause time scales with heap size
    • +
    • Mixed collections can exceed 100ms
    • +
    +
    +
    +

    + A 100ms pause at 10,000 messages/second = 1,000 messages delayed +

    +
    + + +
    +

    Garbage Collection Fundamentals

    +

    Key Terminology

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermDefinition
    Young GenerationWhere new objects are allocated. Collected frequently.
    Old GenerationWhere long-lived objects reside after surviving young GCs.
    PromotionMoving objects from young to old generation.
    Live SetTotal reachable objects. Larger = more GC work.
    Stop-the-WorldAll application threads pause for GC to complete.
    Concurrent CollectionGC runs alongside application threads. No pause.
    +
    + + +
    +

    G1 vs C4: Execution Timeline

    +

    What Happens During Collection

    +
    +

    G1GC (Stop-the-World)

    +
    +
    App
    +
    STOP
    +
    App
    +
    STOP
    +
    App
    +
    MIXED
    +
    App
    +
    +

    Application threads halt during red blocks. Latency spikes occur.

    +
    +
    +

    Azul C4 (Concurrent)

    +
    +
    Application runs continuously
    +
    +
    +
    Mark
    +
    +
    Relocate
    +
    +
    Remap
    +
    +

    GC runs concurrently. Application never stops. Flat latency profile.

    +
    +
    + + +
    +

    G1's Architectural Limitations

    +

    Why Stop-the-World is Unavoidable

    +
    +
    +

    Mixed Collections

    +
      +
    • Must trace entire live set
    • +
    • Pause scales with heap size
    • +
    • 2GB heap: 50-100ms pauses
    • +
    • 4GB heap: 100-200ms pauses
    • +
    +
    +
    +

    Remembered Sets

    +
      +
    • Track old-to-young references
    • +
    • Write barrier on every pointer update
    • +
    • Scanned during young GC
    • +
    • Overhead proportional to cross-refs
    • +
    +
    +
    +
    +

    Compaction Pauses

    +

    When heap fragments, G1 must stop all threads to compact memory. Small objects with random lifetimes trigger frequent compaction. No concurrent solution in G1.

    +
    +
    + + +
    +

    Azul C4: Concurrent by Design

    +

    How Pauseless Collection Works

    +
    +
    +

    Read Barriers

    +
      +
    • Check object state on every read
    • +
    • Relocate objects on-the-fly
    • +
    • No stop-the-world compaction
    • +
    • Hardware-assisted (LVB)
    • +
    +
    +
    +

    No Generations

    +
      +
    • Single heap region
    • +
    • No remembered sets needed
    • +
    • No write barrier overhead
    • +
    • Simpler, more predictable
    • +
    +
    +
    +
    +

    Result: Pause times remain under 1ms regardless of heap size or live set.

    +
    +
    + + +
    +

    Testing GC Behavior: Scenario Approach

    +

    Targeting Specific Collector Weaknesses

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ScenarioRateLive SetG1 Weakness Tested
    STEADY_LOAD200 MB/s512 MBYoung GC pause frequency
    GROWING_HEAP150 MB/s100MB β†’ 2GBMixed collection pause scaling
    PROMOTION_STORM300 MB/s1 GB (50% survival)Old generation pressure
    FRAGMENTATION200 MB/s1 GB fragmentedCompaction pauses
    CROSS_GEN_REFS150 MB/s800 MB old genRemembered set overhead
    +

    + Each scenario uses 4 parallel threads to mirror production workloads. +

    +
    + + +
    +

    CROSS_GEN_REFS: Remembered Set Stress

    +

    Testing G1's Write Barrier Overhead

    +
    
    +private static class RefHolder {
    +    volatile Object youngRef;  // Updated frequently
    +    final byte[] padding;      // 1MB to ensure old gen residence
    +}
    +
    +private void createCrossGenerationalRefs(int bytes, int threads) {
    +    RefHolder[] holders = crossRefHolders.toArray(new RefHolder[0]);
    +
    +    for (int t = 0; t < threads; t++) {
    +        futures[t] = CompletableFuture.runAsync(() -> {
    +            while (remaining > 0) {
    +                byte[] youngObj = new byte[size];
    +                // This write triggers G1's post-write barrier
    +                holders[idx].youngRef = youngObj;
    +                remaining -= size;
    +            }
    +        }, executorService);
    +    }
    +}
    +            
    +

    + G1: Every pointer update marks card table, adds to remembered set.
    + C4: No generations = no remembered sets = no overhead. +

    +
    + + +
    +

    TradeStreamEE Architecture

    +

    Zero-Copy Pipeline for Market Data

    +
    +
    Publisher
    Market Data
    +
    β†’
    +
    SBE
    Binary Encode
    +
    β†’
    +
    Aeron IPC
    Shared Memory
    +
    β†’
    +
    Payara
    WebSocket
    +
    β†’
    +
    Browser
    Dashboard
    +
    +
    +
    +

    Ingestion Layer

    +
      +
    • Aeron IPC: Kernel bypass, shared memory
    • +
    • SBE: Flyweight pattern, zero allocation
    • +
    • Sub-microsecond message latency
    • +
    +
    +
    +

    Application Layer

    +
      +
    • Payara Micro 7: Jakarta EE 11
    • +
    • CDI: Lifecycle management
    • +
    • WebSocket: Real-time push
    • +
    +
    +
    +
    + + +
    +

    SBE: Zero-Copy Message Processing

    +

    The Flyweight Pattern

    +
    
    +// Reusable decoders - no allocation in hot path
    +private final TradeDecoder tradeDecoder = new TradeDecoder();
    +private final MessageHeaderDecoder headerDecoder = new MessageHeaderDecoder();
    +
    +@Override
    +public void onFragment(DirectBuffer buffer, int offset, int length, Header header) {
    +    // Wrap existing buffer - no copy
    +    headerDecoder.wrap(buffer, offset);
    +
    +    // Move decoder "window" over buffer - no allocation
    +    tradeDecoder.wrap(buffer,
    +                     offset + headerDecoder.encodedLength(),
    +                     headerDecoder.blockLength(),
    +                     headerDecoder.version());
    +
    +    // Read directly from buffer
    +    final long timestamp = tradeDecoder.timestamp();
    +    final long price = tradeDecoder.price();
    +    final long quantity = tradeDecoder.quantity();
    +}
    +            
    +

    + Decoders are views over byte buffers. No Java objects created during message processing. +

    +
    + + +
    +

    Aeron: Ultra-Low Latency Transport

    +

    Bypassing the Kernel

    +
    +
    +

    Traditional Messaging

    +
      +
    • TCP/IP socket calls
    • +
    • Kernel context switches
    • +
    • Buffer copies at each layer
    • +
    • Serialization/deserialization
    • +
    • Latency: 10-100+ microseconds
    • +
    +
    +
    +

    Aeron IPC

    +
      +
    • Memory-mapped files
    • +
    • Direct memory access
    • +
    • Zero-copy with SBE
    • +
    • No kernel involvement
    • +
    • Latency: sub-microsecond
    • +
    +
    +
    +
    +

    Aeron's ring buffer in shared memory allows components on the same machine to communicate without network overhead. Combined with SBE, the entire path from publisher to subscriber involves no object allocation.

    +
    +
    + + +
    +

    Payara Micro: Enterprise Runtime

    +

    Jakarta EE 11 for Financial Applications

    +
    +
    +

    Features

    +
      +
    • ~100MB footprint
    • +
    • Fast startup (seconds)
    • +
    • Jakarta CDI for DI
    • +
    • Jakarta WebSocket
    • +
    • Jakarta REST (JAX-RS)
    • +
    • Jakarta Concurrency 3.1
    • +
    +
    +
    +

    Clustering

    +
      +
    • Hazelcast built-in
    • +
    • Automatic discovery
    • +
    • Distributed counters
    • +
    • Session replication
    • +
    • No external infrastructure
    • +
    +
    +
    +
    
    +// Cluster-wide metrics without complex setup
    +@Inject private HazelcastInstance hazelcastInstance;
    +
    +public void init() {
    +    clusterMessageCounter =
    +        hazelcastInstance.getCPSubsystem().getAtomicLong("cluster-message-count");
    +}
    +            
    +
    + + +
    +

    Jakarta Concurrency 3.1

    +

    Virtual Threads for Memory Pressure Testing

    +
    
    +@Resource
    +private ManagedExecutorService executorService;
    +
    +private void allocateTransientGarbageMultiThreaded(int totalBytes, int numThreads) {
    +    int bytesPerThread = totalBytes / numThreads;
    +    CompletableFuture<?>[] futures = new CompletableFuture[numThreads];
    +
    +    for (int t = 0; t < numThreads; t++) {
    +        futures[t] = CompletableFuture.runAsync(() -> {
    +            byte[] garbage = new byte[bytesPerThread];
    +            ThreadLocalRandom.current().nextBytes(garbage);
    +            totalBytesAllocated.addAndGet(bytesPerThread);
    +        }, executorService);
    +    }
    +
    +    CompletableFuture.allOf(futures).join();
    +}
    +            
    +

    + 4 parallel threads simulate production workloads where multiple request handlers allocate concurrently. +

    +
    + + +
    +

    Test Results: G1 vs C4

    +

    Under PROMOTION_STORM (300 MB/sec, 50% survival)

    +
    +
    +
    50-200ms
    +
    G1 Mixed Collection Pauses
    +
    +
    +
    < 1ms
    +
    C4 Maximum Pause
    +
    +
    +
    
    +{
    +  "currentMode": "PROMOTION_STORM",
    +  "allocationRateMBPerSec": 300,
    +  "liveSetSizeMB": 1024,
    +  "percentiles": {
    +    "p50": 0,
    +    "p99": 1,
    +    "max": 1
    +  }
    +}
    +            
    +

    + C4 maintains sub-millisecond pauses regardless of promotion rate or live set size. +

    +
    + + +
    +

    GROWING_HEAP: Live Set Scaling

    +

    100 MB β†’ 2 GB over 60 seconds

    +
    +
    +

    G1 Behavior

    +
      +
    • Young GC: 10-30ms initially
    • +
    • Mixed GC starts at ~500MB
    • +
    • Pause time grows with live set
    • +
    • At 2GB: 100-200ms pauses
    • +
    • Throughput degrades
    • +
    +
    +
    +

    C4 Behavior

    +
      +
    • Pause time: 0-1ms throughout
    • +
    • No mixed collection concept
    • +
    • Live set size irrelevant
    • +
    • At 2GB: still < 1ms
    • +
    • Consistent throughput
    • +
    +
    +
    +

    + G1's pause time scales with heap occupancy. C4's pause time remains constant. +

    +
    + + +
    +

    Business Impact

    +

    Why Pauseless Matters for Trading

    +
    +
    +

    Predictable Latency

    +
      +
    • SLA compliance guaranteed
    • +
    • No jitter during market events
    • +
    • Consistent execution speed
    • +
    • Regulatory requirements met
    • +
    +
    +
    +

    Operational Simplicity

    +
      +
    • No GC tuning required
    • +
    • C4 adapts automatically
    • +
    • Fewer performance engineers
    • +
    • Reduced time-to-production
    • +
    +
    +
    +
    +

    Cost of a 100ms Pause

    +

    At 10,000 trades/second, a 100ms pause delays 1,000 trades. In markets where price moves in milliseconds, delayed trades execute at worse prices. Multiply by trading volume for financial impact.

    +
    +
    + + +
    +

    Deployment Options

    +

    Running TradeStreamEE

    +
    
    +# Single instance - Azul C4 with Aeron
    +./start.sh azul-aeron
    +
    +# Single instance - Standard JDK with G1 (baseline)
    +./start.sh standard-direct
    +
    +# Side-by-side comparison (C4 vs G1 clusters)
    +./start-comparison.sh all
    +            
    +
    +
    +

    Single Instance

    +
      +
    • 8GB heap
    • +
    • Full throughput testing
    • +
    • AERON or DIRECT mode
    • +
    +
    +
    +

    Comparison Stack

    +
      +
    • C4 cluster: ports 8080-8083
    • +
    • G1 cluster: ports 9080-9083
    • +
    • Grafana dashboards included
    • +
    +
    +
    +
    + + +
    +

    Stress Testing API

    +

    Applying Scenarios via REST

    +
    
    +# Apply scenarios
    +curl -X POST http://localhost:8080/api/pressure/mode/STEADY_LOAD
    +curl -X POST http://localhost:8080/api/pressure/mode/GROWING_HEAP
    +curl -X POST http://localhost:8080/api/pressure/mode/PROMOTION_STORM
    +curl -X POST http://localhost:8080/api/pressure/mode/FRAGMENTATION
    +curl -X POST http://localhost:8080/api/pressure/mode/CROSS_GEN_REFS
    +curl -X POST http://localhost:8080/api/pressure/mode/OFF
    +
    +# Get GC statistics
    +curl http://localhost:8080/api/gc/stats
    +
    +# Get current pressure status
    +curl http://localhost:8080/api/pressure/status
    +            
    +

    + The UI provides real-time visualization of GC pause times, percentiles, and allocation rates. +

    +
    + + +
    +

    Technology Stack

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ComponentTechnologyRole
    RuntimeAzul Platform PrimeC4 pauseless garbage collection
    App ServerPayara Micro 7Jakarta EE 11 container
    TransportAeron IPCShared memory messaging
    EncodingSBEZero-copy binary serialization
    ClusteringHazelcastDistributed state and discovery
    MonitoringPrometheus + GrafanaMetrics and visualization
    +
    + + +
    +

    Key Takeaways

    +
      +
    1. G1's stop-the-world pauses are architectural - no tuning eliminates them
    2. +
    3. C4 collects concurrently - application never stops
    4. +
    5. Pause time in G1 scales with live set - larger heaps = longer pauses
    6. +
    7. C4 pause time is constant - regardless of heap or live set size
    8. +
    9. Remembered sets add overhead in G1 - cross-gen refs trigger write barriers
    10. +
    11. C4 has no generations - no remembered sets, no barrier overhead
    12. +
    13. Scenario-based testing exposes weaknesses - targeted stress reveals true behavior
    14. +
    15. Enterprise Java can achieve HFT latency - with the right runtime
    16. +
    +
    + + +
    +

    Resources

    +
    +

    TradeStreamEE Features

    +
      +
    • Scenario-based GC stress testing (5 scenarios)
    • +
    • Real-time pause time visualization
    • +
    • Side-by-side C4 vs G1 comparison
    • +
    • Zero-copy message pipeline (Aeron + SBE)
    • +
    • Hazelcast clustering support
    • +
    • Prometheus/Grafana monitoring
    • +
    +
    +

    Learn More

    +
      +
    • Azul Platform Prime: azul.com/products/prime
    • +
    • Payara Platform: payara.fish
    • +
    • Aeron: aeron.io
    • +
    • SBE: real-logic.github.io/simple-binary-encoding
    • +
    +
    + + +
    + +

    Thank You

    +

    Questions?

    +
    +

    GitHub: github.com/pedanticdev/trader-stream-ee

    +
    +
    +
    +
    + + + + + + + + diff --git a/src/test/java/fish/payara/trader/BasicFunctionalityTest.java b/src/test/java/fish/payara/trader/BasicFunctionalityTest.java index f15c20e..afa5100 100644 --- a/src/test/java/fish/payara/trader/BasicFunctionalityTest.java +++ b/src/test/java/fish/payara/trader/BasicFunctionalityTest.java @@ -17,15 +17,15 @@ class BasicFunctionalityTest { void shouldVerifyAllocationModesWorkCorrectly() { // Test AllocationMode enum assertEquals(AllocationMode.OFF, AllocationMode.valueOf("OFF")); - assertEquals(AllocationMode.LOW, AllocationMode.valueOf("LOW")); - assertEquals(AllocationMode.MEDIUM, AllocationMode.valueOf("MEDIUM")); - assertEquals(AllocationMode.HIGH, AllocationMode.valueOf("HIGH")); - assertEquals(AllocationMode.EXTREME, AllocationMode.valueOf("EXTREME")); + assertEquals(AllocationMode.STEADY_LOAD, AllocationMode.valueOf("STEADY_LOAD")); + assertEquals(AllocationMode.GROWING_HEAP, AllocationMode.valueOf("GROWING_HEAP")); + assertEquals(AllocationMode.PROMOTION_STORM, AllocationMode.valueOf("PROMOTION_STORM")); + assertEquals(AllocationMode.FRAGMENTATION, AllocationMode.valueOf("FRAGMENTATION")); // Test allocation rates - assertEquals(0L, AllocationMode.OFF.getBytesPerSecond()); - assertTrue(AllocationMode.LOW.getBytesPerSecond() > 0); - assertTrue(AllocationMode.EXTREME.getBytesPerSecond() > AllocationMode.LOW.getBytesPerSecond()); + assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); + assertTrue(AllocationMode.STEADY_LOAD.getAllocationRateMBPerSec() > 0); + // Note: STEADY_LOAD rate (200) is > OFF (0) } @Test diff --git a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java index 18b3eae..221dceb 100644 --- a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java +++ b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java @@ -21,64 +21,50 @@ class EnumValuesTests { @DisplayName("Should have all required allocation modes") void shouldHaveAllRequiredAllocationModes() { AllocationMode[] modes = AllocationMode.values(); - assertEquals(5, modes.length, "Should have exactly 5 allocation modes"); + assertEquals(6, modes.length, "Should have exactly 6 allocation modes"); assertTrue(containsMode(modes, AllocationMode.OFF), "Should contain OFF mode"); - assertTrue(containsMode(modes, AllocationMode.LOW), "Should contain LOW mode"); - assertTrue(containsMode(modes, AllocationMode.MEDIUM), "Should contain MEDIUM mode"); - assertTrue(containsMode(modes, AllocationMode.HIGH), "Should contain HIGH mode"); - assertTrue(containsMode(modes, AllocationMode.EXTREME), "Should contain EXTREME mode"); - } - - @Test - @DisplayName("Should have correct enum order from low to high pressure") - void shouldHaveCorrectEnumOrderFromLowToHighPressure() { - AllocationMode[] modes = AllocationMode.values(); - - assertEquals(AllocationMode.OFF, modes[0], "OFF should be first"); - assertEquals(AllocationMode.LOW, modes[1], "LOW should be second"); - assertEquals(AllocationMode.MEDIUM, modes[2], "MEDIUM should be third"); - assertEquals(AllocationMode.HIGH, modes[3], "HIGH should be fourth"); - assertEquals(AllocationMode.EXTREME, modes[4], "EXTREME should be last"); + assertTrue( + containsMode(modes, AllocationMode.STEADY_LOAD), "Should contain STEADY_LOAD mode"); + assertTrue( + containsMode(modes, AllocationMode.GROWING_HEAP), "Should contain GROWING_HEAP mode"); + assertTrue( + containsMode(modes, AllocationMode.PROMOTION_STORM), + "Should contain PROMOTION_STORM mode"); + assertTrue( + containsMode(modes, AllocationMode.FRAGMENTATION), "Should contain FRAGMENTATION mode"); + assertTrue( + containsMode(modes, AllocationMode.CROSS_GEN_REFS), "Should contain CROSS_GEN_REFS mode"); } } @Nested - @DisplayName("Allocation Properties Tests") - class AllocationPropertiesTests { + @DisplayName("Scenario Properties Tests") + class ScenarioPropertiesTests { @ParameterizedTest @EnumSource(AllocationMode.class) - @DisplayName("Should have correct allocation per iteration values") - void shouldHaveCorrectAllocationPerIterationValues(AllocationMode mode) { - int expected = - switch (mode) { - case OFF -> 0; - case LOW -> 20; - case MEDIUM -> 200; - case HIGH -> 10000; - case EXTREME -> 40000; - }; + @DisplayName("Should have non-null scenario type") + void shouldHaveNonNullScenarioType(AllocationMode mode) { + assertNotNull(mode.getScenarioType(), "ScenarioType should not be null"); + } - assertEquals( - expected, - mode.getAllocationsPerIteration(), - String.format("Mode %s should have %d allocations per iteration", mode.name(), expected)); + @Test + @DisplayName("Should have correct scenario types") + void shouldHaveCorrectScenarioTypes() { + assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); + assertEquals(ScenarioType.STEADY, AllocationMode.STEADY_LOAD.getScenarioType()); + assertEquals(ScenarioType.GROWING, AllocationMode.GROWING_HEAP.getScenarioType()); + assertEquals(ScenarioType.PROMOTION, AllocationMode.PROMOTION_STORM.getScenarioType()); + assertEquals(ScenarioType.FRAGMENTATION, AllocationMode.FRAGMENTATION.getScenarioType()); + assertEquals(ScenarioType.CROSS_REF, AllocationMode.CROSS_GEN_REFS.getScenarioType()); } @ParameterizedTest @EnumSource(AllocationMode.class) - @DisplayName("Should have correct bytes per allocation values") - void shouldHaveCorrectBytesPerAllocationValues(AllocationMode mode) { - int expected = - switch (mode) { - case OFF -> 0; - default -> 10240; - }; - assertEquals( - expected, - mode.getBytesPerAllocation(), - String.format("Mode %s should have %d bytes per allocation", mode.name(), expected)); + @DisplayName("Should have valid allocation rates") + void shouldHaveValidAllocationRates(AllocationMode mode) { + assertTrue(mode.getAllocationRateMBPerSec() >= 0, "Allocation rate should be non-negative"); } @ParameterizedTest @@ -89,170 +75,6 @@ void shouldHaveMeaningfulDescriptions(AllocationMode mode) { assertNotNull(description, "Description should not be null"); assertFalse(description.trim().isEmpty(), "Description should not be empty"); - assertTrue(description.length() > 10, "Description should be descriptive"); - } - } - - @Nested - @DisplayName("Bytes Per Second Calculation Tests") - class BytesPerSecondCalculationTests { - - @Test - @DisplayName("Should calculate bytes per second correctly for OFF mode") - void shouldCalculateBytesPerSecondCorrectlyForOffMode() { - assertEquals( - 0L, - AllocationMode.OFF.getBytesPerSecond(), - "OFF mode should allocate 0 bytes per second"); - } - - @Test - @DisplayName("Should calculate bytes per second correctly for LOW mode") - void shouldCalculateBytesPerSecondCorrectlyForLowMode() { - // 20 allocations * 10240 bytes * 10 iterations/sec = 2,048,000 bytes/sec - assertEquals( - 2_048_000L, AllocationMode.LOW.getBytesPerSecond(), "LOW mode should allocate 2 MB/sec"); - } - - @Test - @DisplayName("Should calculate bytes per second correctly for MEDIUM mode") - void shouldCalculateBytesPerSecondCorrectlyForMediumMode() { - // 200 allocations * 10240 bytes * 10 iterations/sec = 20,480,000 bytes/sec - assertEquals( - 20_480_000L, - AllocationMode.MEDIUM.getBytesPerSecond(), - "MEDIUM mode should allocate 20 MB/sec"); - } - - @Test - @DisplayName("Should calculate bytes per second correctly for HIGH mode") - void shouldCalculateBytesPerSecondCorrectlyForHighMode() { - // 10000 allocations * 10240 bytes * 10 iterations/sec = 1,024,000,000 bytes/sec - assertEquals( - 1_024_000_000L, - AllocationMode.HIGH.getBytesPerSecond(), - "HIGH mode should allocate 1 GB/sec"); - } - - @Test - @DisplayName("Should calculate bytes per second correctly for EXTREME mode") - void shouldCalculateBytesPerSecondCorrectlyForExtremeMode() { - // 40000 allocations * 10240 bytes * 10 iterations/sec = 4,096,000,000 bytes/sec - assertEquals( - 4_096_000_000L, - AllocationMode.EXTREME.getBytesPerSecond(), - "EXTREME mode should allocate 4 GB/sec"); - } - } - - @Nested - @DisplayName("Progressive Intensity Tests") - class ProgressiveIntensityTests { - - @Test - @DisplayName("Should have progressively increasing allocation rates") - void shouldHaveProgressivelyIncreasingAllocationRates() { - long previousRate = -1; - - for (AllocationMode mode : AllocationMode.values()) { - long currentRate = mode.getBytesPerSecond(); - - assertTrue( - currentRate >= previousRate, - String.format( - "%s (%d bytes/sec) should be >= previous rate (%d)", - mode.name(), currentRate, previousRate)); - - previousRate = currentRate; - } - } - - @Test - @DisplayName("Should have monotonic allocation per iteration progression") - void shouldHaveMonotonicAllocationPerIterationProgression() { - int previousAllocations = -1; - - for (AllocationMode mode : AllocationMode.values()) { - int currentAllocations = mode.getAllocationsPerIteration(); - - assertTrue( - currentAllocations >= previousAllocations, - String.format( - "%s (%d allocations) should be >= previous (%d)", - mode.name(), currentAllocations, previousAllocations)); - - previousAllocations = currentAllocations; - } - } - - @Test - @DisplayName("Should have significant gaps between modes") - void shouldHaveSignificantGapsBetweenModes() { - // Verify that there are meaningful differences between modes - assertTrue( - AllocationMode.LOW.getBytesPerSecond() > AllocationMode.OFF.getBytesPerSecond(), - "LOW should be significantly higher than OFF"); - - assertTrue( - AllocationMode.MEDIUM.getBytesPerSecond() > AllocationMode.LOW.getBytesPerSecond() * 5, - "MEDIUM should be at least 5x higher than LOW"); - - assertTrue( - AllocationMode.HIGH.getBytesPerSecond() > AllocationMode.MEDIUM.getBytesPerSecond() * 40, - "HIGH should be at least 40x higher than MEDIUM"); - - assertTrue( - AllocationMode.EXTREME.getBytesPerSecond() > AllocationMode.HIGH.getBytesPerSecond() * 2, - "EXTREME should be at least 2x higher than HIGH"); - } - } - - @Nested - @DisplayName("Description Content Tests") - class DescriptionContentTests { - - @Test - @DisplayName("Descriptions should contain pressure level indicators") - void descriptionsShouldContainPressureLevelIndicators() { - assertTrue( - AllocationMode.LOW.getDescription().contains("Light"), - "LOW description should contain 'Light'"); - - assertTrue( - AllocationMode.MEDIUM.getDescription().contains("Moderate"), - "MEDIUM description should contain 'Moderate'"); - - assertTrue( - AllocationMode.HIGH.getDescription().contains("Heavy"), - "HIGH description should contain 'Heavy'"); - - assertTrue( - AllocationMode.EXTREME.getDescription().contains("Extreme"), - "EXTREME description should contain 'Extreme'"); - - assertTrue( - AllocationMode.OFF.getDescription().contains("No"), - "OFF description should contain 'No'"); - } - - @Test - @DisplayName("Descriptions should contain rate information") - void descriptionsShouldContainRateInformation() { - assertTrue( - AllocationMode.LOW.getDescription().contains("2 MB/sec"), - "LOW description should contain rate information"); - - assertTrue( - AllocationMode.MEDIUM.getDescription().contains("20 MB/sec"), - "MEDIUM description should contain rate information"); - - assertTrue( - AllocationMode.HIGH.getDescription().contains("1 GB/sec"), - "HIGH description should contain rate information"); - - assertTrue( - AllocationMode.EXTREME.getDescription().contains("4 GB/sec"), - "EXTREME description should contain rate information"); } } @@ -261,33 +83,15 @@ void descriptionsShouldContainRateInformation() { class EdgeCasesTests { @Test - @DisplayName("Should handle zero allocations correctly") - void shouldHandleZeroAllocationsCorrectly() { - assertEquals( - 0, - AllocationMode.OFF.getAllocationsPerIteration(), - "OFF mode should have zero allocations"); - - assertEquals( - 0L, - AllocationMode.OFF.getBytesPerSecond(), - "OFF mode should result in zero bytes per second"); - } - - @Test - @DisplayName("Should handle large allocations correctly") - void shouldHandleLargeAllocationsCorrectly() { - long extremeRate = AllocationMode.EXTREME.getBytesPerSecond(); - - assertTrue( - extremeRate > 1_000_000_000L, // 1GB - "EXTREME mode should handle large allocations (>1GB/sec)"); - - assertEquals(4_096_000_000L, extremeRate, "EXTREME mode should handle exactly 4GB/sec"); + @DisplayName("Should handle OFF mode correctly") + void shouldHandleOffModeCorrectly() { + assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); + assertEquals(0, AllocationMode.OFF.getLiveSetSizeMB()); + assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); } @ParameterizedTest - @ValueSource(strings = {"OFF", "LOW", "MEDIUM", "HIGH", "EXTREME"}) + @ValueSource(strings = {"OFF", "STEADY_LOAD", "GROWING_HEAP", "PROMOTION_STORM"}) @DisplayName("Should handle enum valueOf correctly") void shouldHandleEnumValueOfCorrectly(String modeName) { assertDoesNotThrow( @@ -317,34 +121,6 @@ void shouldThrowIllegalArgumentExceptionForInvalidModeNames() { } } - @Nested - @DisplayName("Constants Validation Tests") - class ConstantsValidationTests { - - @Test - @DisplayName("Should validate constant values") - void shouldValidateConstantValues() { - // Validate that bytes per allocation follows expected pattern - for (AllocationMode mode : AllocationMode.values()) { - int expectedBytes = (mode == AllocationMode.OFF) ? 0 : 10240; - assertEquals( - expectedBytes, - mode.getBytesPerAllocation(), - String.format("%s should use %d bytes per allocation", mode.name(), expectedBytes)); - } - - // Validate that calculation formula is consistent - for (AllocationMode mode : AllocationMode.values()) { - long expected = - (long) mode.getAllocationsPerIteration() * mode.getBytesPerAllocation() * 10; - assertEquals( - expected, - mode.getBytesPerSecond(), - String.format("Calculation should be consistent for %s", mode.name())); - } - } - } - /** Helper method to check if array contains specific mode */ private boolean containsMode(AllocationMode[] modes, AllocationMode targetMode) { for (AllocationMode mode : modes) { diff --git a/src/test/java/fish/payara/trader/pressure/patterns/HFTPatternRegistryTest.java b/src/test/java/fish/payara/trader/pressure/patterns/HFTPatternRegistryTest.java deleted file mode 100644 index 1bf83e7..0000000 --- a/src/test/java/fish/payara/trader/pressure/patterns/HFTPatternRegistryTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("HFTPatternRegistry Tests") -class HFTPatternRegistryTest { - - private final HFTPatternRegistry registry = new HFTPatternRegistry(); - - @Test - @DisplayName("Registry contains expected patterns") - void testGetAllPatterns() { - var patterns = registry.getAllPatterns(); - - assertEquals(3, patterns.size(), "Registry should contain exactly 3 patterns"); - - assertTrue( - patterns.stream().anyMatch(p -> p instanceof OrderBookPattern), - "Registry should contain OrderBookPattern"); - assertTrue( - patterns.stream().anyMatch(p -> p instanceof MarketTickPattern), - "Registry should contain MarketTickPattern"); - assertTrue( - patterns.stream().anyMatch(p -> p instanceof MarketDepthPattern), - "Registry should contain MarketDepthPattern"); - } - - @Test - @DisplayName("Pattern count returns correct value") - void testGetPatternCount() { - assertEquals(3, registry.getPatternCount(), "Pattern count should be 3"); - } - - @Test - @DisplayName("Round-robin distribution is even") - void testRoundRobinDistribution() { - Map counts = new HashMap<>(); - - // Select 300 patterns (100 rounds of 3 patterns) - for (int i = 0; i < 300; i++) { - AllocationPattern pattern = registry.selectPattern(); - counts.merge(pattern.getName(), 1, Integer::sum); - } - - // Each pattern should appear exactly 100 times - assertEquals(100, counts.get("OrderBook"), "OrderBook should appear 100 times"); - assertEquals(100, counts.get("MarketTick"), "MarketTick should appear 100 times"); - assertEquals(100, counts.get("MarketDepth"), "MarketDepth should appear 100 times"); - } - - @Test - @DisplayName("Pattern selection never returns null") - void testSelectionNeverNull() { - for (int i = 0; i < 1000; i++) { - assertNotNull(registry.selectPattern(), "Pattern selection should never return null"); - } - } - - @Test - @DisplayName("Pattern selection cycles correctly") - void testPatternCycling() { - // First 3 selections should be in order: OrderBook, Tick, Depth - AllocationPattern p1 = registry.selectPattern(); - AllocationPattern p2 = registry.selectPattern(); - AllocationPattern p3 = registry.selectPattern(); - AllocationPattern p4 = registry.selectPattern(); // Should cycle back to OrderBook - - assertEquals("OrderBook", p1.getName(), "First pattern should be OrderBook"); - assertEquals("MarketTick", p2.getName(), "Second pattern should be MarketTick"); - assertEquals("MarketDepth", p3.getName(), "Third pattern should be MarketDepth"); - assertEquals("OrderBook", p4.getName(), "Fourth pattern should cycle back to OrderBook"); - } - - @Test - @DisplayName("Registry is thread-safe for concurrent access") - void testThreadSafety() throws InterruptedException { - final int THREADS = 10; - final int ITERATIONS = 100; - Thread[] threads = new Thread[THREADS]; - Map totalCounts = new HashMap<>(); - - for (int i = 0; i < THREADS; i++) { - threads[i] = - new Thread( - () -> { - for (int j = 0; j < ITERATIONS; j++) { - AllocationPattern pattern = registry.selectPattern(); - synchronized (totalCounts) { - totalCounts.merge(pattern.getName(), 1, Integer::sum); - } - } - }); - threads[i].start(); - } - - for (Thread thread : threads) { - thread.join(); - } - - // Total selections: 10 threads Γ— 100 iterations = 1000 - int totalSelections = totalCounts.values().stream().mapToInt(Integer::intValue).sum(); - assertEquals(1000, totalSelections, "Total selections should be 1000"); - - // Each pattern should get approximately 333 selections (Β±tolerance for thread timing) - int expectedPerPattern = 1000 / 3; - int tolerance = 50; // Allow some variance due to concurrent access - - for (String patternName : new String[] {"OrderBook", "MarketTick", "MarketDepth"}) { - int count = totalCounts.getOrDefault(patternName, 0); - assertTrue( - Math.abs(count - expectedPerPattern) <= tolerance, - String.format( - "Pattern %s should have ~%d selections, got %d", - patternName, expectedPerPattern, count)); - } - } -} diff --git a/src/test/java/fish/payara/trader/pressure/patterns/MarketDepthPatternTest.java b/src/test/java/fish/payara/trader/pressure/patterns/MarketDepthPatternTest.java deleted file mode 100644 index b13e985..0000000 --- a/src/test/java/fish/payara/trader/pressure/patterns/MarketDepthPatternTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("MarketDepthPattern Tests") -class MarketDepthPatternTest { - - private final MarketDepthPattern pattern = new MarketDepthPattern(); - - @Test - @DisplayName("Allocate creates DepthSnapshot with bid/ask arrays") - void testAllocate() { - Object result = pattern.allocate(6000); - - assertNotNull(result, "Allocated object should not be null"); - assertTrue( - result instanceof MarketDepthPattern.DepthSnapshot, - "Allocated object should be DepthSnapshot instance"); - - MarketDepthPattern.DepthSnapshot snapshot = (MarketDepthPattern.DepthSnapshot) result; - assertNotNull(snapshot.symbol, "Snapshot symbol should not be null"); - assertNotNull(snapshot.bidPrices, "Bid prices array should not be null"); - assertNotNull(snapshot.bidSizes, "Bid sizes array should not be null"); - assertNotNull(snapshot.askPrices, "Ask prices array should not be null"); - assertNotNull(snapshot.askSizes, "Ask sizes array should not be null"); - assertTrue(snapshot.timestamp > 0, "Timestamp should be positive"); - - // Verify array lengths match - assertEquals( - snapshot.bidPrices.length, - snapshot.bidSizes.length, - "Bid prices and sizes should have same length"); - assertEquals( - snapshot.askPrices.length, - snapshot.askSizes.length, - "Ask prices and sizes should have same length"); - assertEquals( - snapshot.bidPrices.length, - snapshot.askPrices.length, - "Bid and ask sides should have same depth"); - - // Verify minimum clamping - assertTrue( - snapshot.bidPrices.length >= 10, "Depth should have at least 10 levels (minimum clamping)"); - - // Verify data validity - for (int i = 0; i < snapshot.bidPrices.length; i++) { - assertTrue(snapshot.bidPrices[i] > 0, "Bid price should be positive"); - assertTrue(snapshot.bidSizes[i] > 0, "Bid size should be positive"); - assertTrue(snapshot.askPrices[i] > 0, "Ask price should be positive"); - assertTrue(snapshot.askSizes[i] > 0, "Ask size should be positive"); - } - } - - @Test - @DisplayName("Pattern name is MarketDepth") - void testGetName() { - assertEquals("MarketDepth", pattern.getName(), "Pattern name should be 'MarketDepth'"); - } - - @Test - @DisplayName("Multiple allocations create different objects") - void testMultipleAllocations() { - Object obj1 = pattern.allocate(6000); - Object obj2 = pattern.allocate(6000); - - assertNotSame(obj1, obj2, "Multiple allocations should create different object instances"); - } - - @Test - @DisplayName("Depth levels respect clamping boundaries") - void testSizeClamping() { - // Small allocation should clamp to 10 minimum - Object small = pattern.allocate(100); - MarketDepthPattern.DepthSnapshot smallSnapshot = (MarketDepthPattern.DepthSnapshot) small; - assertTrue( - smallSnapshot.bidPrices.length >= 10, "Small allocation should clamp to minimum 10 levels"); - - // Large allocation should clamp to 100 maximum - Object large = pattern.allocate(100000); - MarketDepthPattern.DepthSnapshot largeSnapshot = (MarketDepthPattern.DepthSnapshot) large; - assertTrue( - largeSnapshot.bidPrices.length <= 100, - "Large allocation should clamp to maximum 100 levels"); - } - - @Test - @DisplayName("Bid prices decrease with depth, ask prices increase") - void testPriceLadderStructure() { - Object result = pattern.allocate(6000); - MarketDepthPattern.DepthSnapshot snapshot = (MarketDepthPattern.DepthSnapshot) result; - - // Bid prices should generally decrease (away from best bid) - boolean bidDecreasing = true; - for (int i = 1; i < snapshot.bidPrices.length; i++) { - if (snapshot.bidPrices[i] > snapshot.bidPrices[i - 1]) { - bidDecreasing = false; - break; - } - } - - // Ask prices should generally increase (away from best ask) - boolean askIncreasing = true; - for (int i = 1; i < snapshot.askPrices.length; i++) { - if (snapshot.askPrices[i] < snapshot.askPrices[i - 1]) { - askIncreasing = false; - break; - } - } - - assertTrue(bidDecreasing, "Bid prices should decrease with depth"); - assertTrue(askIncreasing, "Ask prices should increase with depth"); - } - - @Test - @DisplayName("Bid prices are below ask prices (no crossed market)") - void testNoCrossedMarket() { - Object result = pattern.allocate(6000); - MarketDepthPattern.DepthSnapshot snapshot = (MarketDepthPattern.DepthSnapshot) result; - - // Best bid (index 0) should be below best ask (index 0) - assertTrue( - snapshot.bidPrices[0] < snapshot.askPrices[0], - "Best bid should be below best ask (no crossed market)"); - } -} diff --git a/src/test/java/fish/payara/trader/pressure/patterns/MarketTickPatternTest.java b/src/test/java/fish/payara/trader/pressure/patterns/MarketTickPatternTest.java deleted file mode 100644 index 9763525..0000000 --- a/src/test/java/fish/payara/trader/pressure/patterns/MarketTickPatternTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("MarketTickPattern Tests") -class MarketTickPatternTest { - - private final MarketTickPattern pattern = new MarketTickPattern(); - - @Test - @DisplayName("Allocate creates TickBatch with primitive arrays") - void testAllocate() { - Object result = pattern.allocate(4000); - - assertNotNull(result, "Allocated object should not be null"); - assertTrue( - result instanceof MarketTickPattern.TickBatch, - "Allocated object should be TickBatch instance"); - - MarketTickPattern.TickBatch batch = (MarketTickPattern.TickBatch) result; - assertNotNull(batch.symbol, "Batch symbol should not be null"); - assertNotNull(batch.prices, "Prices array should not be null"); - assertNotNull(batch.volumes, "Volumes array should not be null"); - assertNotNull(batch.timestamps, "Timestamps array should not be null"); - - // Verify array lengths match - assertEquals( - batch.prices.length, - batch.volumes.length, - "Prices and volumes arrays should have same length"); - assertEquals( - batch.prices.length, - batch.timestamps.length, - "Prices and timestamps arrays should have same length"); - - // Verify minimum size clamping - assertTrue(batch.prices.length >= 50, "Batch should have at least 50 ticks (minimum clamping)"); - - // Verify data validity - for (int i = 0; i < batch.prices.length; i++) { - assertTrue(batch.prices[i] > 0, "Price should be positive"); - assertTrue(batch.volumes[i] > 0, "Volume should be positive"); - assertTrue(batch.timestamps[i] > 0, "Timestamp should be positive"); - } - } - - @Test - @DisplayName("Pattern name is MarketTick") - void testGetName() { - assertEquals("MarketTick", pattern.getName(), "Pattern name should be 'MarketTick'"); - } - - @Test - @DisplayName("Multiple allocations create different objects") - void testMultipleAllocations() { - Object obj1 = pattern.allocate(4000); - Object obj2 = pattern.allocate(4000); - - assertNotSame(obj1, obj2, "Multiple allocations should create different object instances"); - } - - @Test - @DisplayName("Tick batch size respects clamping boundaries") - void testSizeClamping() { - // Small allocation should clamp to 50 minimum - Object small = pattern.allocate(100); - MarketTickPattern.TickBatch smallBatch = (MarketTickPattern.TickBatch) small; - assertTrue(smallBatch.prices.length >= 50, "Small allocation should clamp to minimum 50 ticks"); - - // Large allocation should clamp to 200 maximum - Object large = pattern.allocate(100000); - MarketTickPattern.TickBatch largeBatch = (MarketTickPattern.TickBatch) large; - assertTrue( - largeBatch.prices.length <= 200, "Large allocation should clamp to maximum 200 ticks"); - } - - @Test - @DisplayName("Tick prices show realistic variation") - void testPriceVariation() { - Object result = pattern.allocate(4000); - MarketTickPattern.TickBatch batch = (MarketTickPattern.TickBatch) result; - - // Check that not all prices are identical (should have random walk) - double firstPrice = batch.prices[0]; - boolean hasVariation = false; - - for (int i = 1; i < batch.prices.length; i++) { - if (Math.abs(batch.prices[i] - firstPrice) > 0.01) { - hasVariation = true; - break; - } - } - - assertTrue(hasVariation, "Prices should show variation (random walk behavior)"); - } -} diff --git a/src/test/java/fish/payara/trader/pressure/patterns/OrderBookPatternTest.java b/src/test/java/fish/payara/trader/pressure/patterns/OrderBookPatternTest.java deleted file mode 100644 index a751e68..0000000 --- a/src/test/java/fish/payara/trader/pressure/patterns/OrderBookPatternTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package fish.payara.trader.pressure.patterns; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("OrderBookPattern Tests") -class OrderBookPatternTest { - - private final OrderBookPattern pattern = new OrderBookPattern(); - - @Test - @DisplayName("Allocate creates OrderBook with expected structure") - void testAllocate() { - Object result = pattern.allocate(5000); - - assertNotNull(result, "Allocated object should not be null"); - assertTrue( - result instanceof OrderBookPattern.OrderBook, - "Allocated object should be OrderBook instance"); - - OrderBookPattern.OrderBook book = (OrderBookPattern.OrderBook) result; - assertNotNull(book.symbol, "Book symbol should not be null"); - assertNotNull(book.levels, "Book levels should not be null"); - assertTrue(book.levels.length > 0, "Book should have at least one level"); - - // Verify levels contain orders - for (OrderBookPattern.PriceLevel level : book.levels) { - assertNotNull(level, "Price level should not be null"); - assertNotNull(level.orders, "Level orders array should not be null"); - assertTrue(level.orders.length > 0, "Level should have at least one order"); - - // Verify orders have valid data - for (OrderBookPattern.Order order : level.orders) { - assertNotNull(order, "Order should not be null"); - assertTrue(order.quantity > 0, "Order quantity should be positive"); - assertTrue(order.timestamp > 0, "Order timestamp should be positive"); - } - } - } - - @Test - @DisplayName("Pattern name is OrderBook") - void testGetName() { - assertEquals("OrderBook", pattern.getName(), "Pattern name should be 'OrderBook'"); - } - - @Test - @DisplayName("Multiple allocations create different objects") - void testMultipleAllocations() { - Object obj1 = pattern.allocate(5000); - Object obj2 = pattern.allocate(5000); - - assertNotSame(obj1, obj2, "Multiple allocations should create different object instances"); - } - - @Test - @DisplayName("Allocation respects approximate byte size clamping") - void testAllocationSizeClamping() { - // Small allocation should clamp to minimum - Object small = pattern.allocate(100); - OrderBookPattern.OrderBook smallBook = (OrderBookPattern.OrderBook) small; - assertTrue(smallBook.levels.length > 0, "Small allocation should still create valid book"); - - // Large allocation should clamp to maximum - Object large = pattern.allocate(100000); - OrderBookPattern.OrderBook largeBook = (OrderBookPattern.OrderBook) large; - assertTrue(largeBook.levels.length > 0, "Large allocation should create valid book"); - } - - @Test - @DisplayName("Order book contains both bid and ask sides") - void testBidAskStructure() { - Object result = pattern.allocate(5000); - OrderBookPattern.OrderBook book = (OrderBookPattern.OrderBook) result; - - boolean hasBid = false; - boolean hasAsk = false; - - for (OrderBookPattern.PriceLevel level : book.levels) { - if (level.isBid) { - hasBid = true; - } else { - hasAsk = true; - } - } - - assertTrue(hasBid || hasAsk, "Book should contain at least one side (bid or ask)"); - } -} diff --git a/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java b/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java index a4e3397..863b737 100644 --- a/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java @@ -68,7 +68,7 @@ void shouldReturnGCPauseStats() { @Test @DisplayName("Should return accurate comparison data") void shouldReturnAccurateComparisonData() { - when(memoryPressureService.getCurrentMode()).thenReturn(AllocationMode.MEDIUM); + when(memoryPressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); when(publisher.getMessagesPublished()).thenReturn(5000L); when(gcStatsService.collectGCStats()).thenReturn(Collections.emptyList()); @@ -82,7 +82,7 @@ void shouldReturnAccurateComparisonData() { @SuppressWarnings("unchecked") Map entity = (Map) response.getEntity(); - assertEquals(AllocationMode.MEDIUM, entity.get("allocationMode")); + assertEquals(AllocationMode.STEADY_LOAD, entity.get("allocationMode")); assertEquals(5000L, entity.get("messageRate")); assertEquals(10.0, ((Number) entity.get("pauseP50Ms")).doubleValue()); assertEquals(50L, entity.get("pauseMaxMs")); diff --git a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java index a64d7ea..af99471 100644 --- a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java @@ -6,7 +6,6 @@ import fish.payara.trader.pressure.AllocationMode; import fish.payara.trader.pressure.MemoryPressureService; import jakarta.ws.rs.core.Response; -import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -26,7 +25,7 @@ class MemoryPressureResourceTest { @Test @DisplayName("Should return current status") void shouldReturnCurrentStatus() { - when(pressureService.getCurrentMode()).thenReturn(AllocationMode.LOW); + when(pressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); when(pressureService.isRunning()).thenReturn(true); Response response = resource.getStatus(); @@ -34,22 +33,22 @@ void shouldReturnCurrentStatus() { assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); @SuppressWarnings("unchecked") Map entity = (Map) response.getEntity(); - assertEquals("LOW", entity.get("currentMode")); + assertEquals("STEADY_LOAD", entity.get("currentMode")); assertEquals(true, entity.get("running")); } @Test @DisplayName("Should set allocation mode successfully") void shouldSetAllocationModeSuccessfully() { - Response response = resource.setMode("high"); + Response response = resource.setMode("steady_load"); assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(pressureService).setAllocationMode(AllocationMode.HIGH); + verify(pressureService).setAllocationMode(AllocationMode.STEADY_LOAD); @SuppressWarnings("unchecked") Map entity = (Map) response.getEntity(); assertTrue((Boolean) entity.get("success")); - assertEquals("HIGH", entity.get("mode")); + assertEquals("STEADY_LOAD", entity.get("mode")); } @Test @@ -64,32 +63,6 @@ void shouldReturnBadRequestForInvalidMode() { assertTrue(((String) entity.get("error")).contains("Invalid mode")); } - @Test - @DisplayName("Should apply scenario successfully") - void shouldApplyScenarioSuccessfully() { - Response response = resource.applyScenario("demo_stress"); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(pressureService).setAllocationMode(AllocationMode.HIGH); - - @SuppressWarnings("unchecked") - Map entity = (Map) response.getEntity(); - assertEquals("DEMO_STRESS", entity.get("scenario")); - assertEquals("applied", entity.get("status")); - } - - @Test - @DisplayName("Should list all scenarios") - void shouldListAllScenarios() { - Response response = resource.listScenarios(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - List> entity = (List>) response.getEntity(); - assertFalse(entity.isEmpty()); - assertTrue(entity.stream().anyMatch(s -> s.get("name").equals("DEMO_EXTREME"))); - } - @Test @DisplayName("Should return all modes") void shouldReturnAllModes() { @@ -99,9 +72,7 @@ void shouldReturnAllModes() { @SuppressWarnings("unchecked") Map> entity = (Map>) response.getEntity(); - assertTrue(entity.containsKey("EXTREME")); - assertEquals( - "4 GB/sec - Extreme pressure", - ((Map) entity.get("EXTREME")).get("description")); + assertTrue(entity.containsKey("STEADY_LOAD")); + assertTrue(entity.containsKey("PROMOTION_STORM")); } } From 9a8c8062000eaed72fb47652412b8ae380f75d7b Mon Sep 17 00:00:00 2001 From: Luqman Saeed Date: Tue, 30 Dec 2025 10:31:39 +0000 Subject: [PATCH 3/6] Fix C4 name identification --- src/main/java/fish/payara/trader/rest/GCStatsResource.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/fish/payara/trader/rest/GCStatsResource.java b/src/main/java/fish/payara/trader/rest/GCStatsResource.java index bb19229..a914331 100644 --- a/src/main/java/fish/payara/trader/rest/GCStatsResource.java +++ b/src/main/java/fish/payara/trader/rest/GCStatsResource.java @@ -80,14 +80,13 @@ public Response getComparison() { gcBeans.stream().map(GarbageCollectorMXBean::getName).collect(Collectors.joining(", ")); boolean isAzulC4 = - jvmVendor != null && (jvmVendor.contains("Azul") || jvmName.contains("Zing")); + gcName.toLowerCase().contains("c4") || jvmName.toLowerCase().contains("zing"); comparison.put("jvmVendor", jvmVendor); comparison.put("jvmName", jvmName); comparison.put("gcCollectors", gcName); comparison.put("isAzulC4", isAzulC4); comparison.put("heapSizeMB", Runtime.getRuntime().maxMemory() / (1024 * 1024)); - comparison.put("allocationMode", memoryPressureService.getCurrentMode()); comparison.put( "allocationRateMBps", memoryPressureService.getCurrentMode().getAllocationRateMBPerSec()); From e6330740a61fa2894d0319ea0956988228af4db8 Mon Sep 17 00:00:00 2001 From: Luqman Saeed Date: Tue, 30 Dec 2025 12:08:48 +0000 Subject: [PATCH 4/6] Use bundled eclipse formatter with spotless --- pom.xml | 7 +- .../payara/resource/HelloWorldResource.java | 51 +- .../trader/aeron/AeronSubscriberBean.java | 225 ++-- .../aeron/MarketDataFragmentHandler.java | 498 ++++---- .../trader/aeron/MarketDataPublisher.java | 1009 ++++++++-------- .../trader/concurrency/ConcurrencyConfig.java | 11 +- .../concurrency/VirtualThreadExecutor.java | 3 +- .../java/fish/payara/trader/gc/GCStats.java | 238 ++-- .../fish/payara/trader/gc/GCStatsService.java | 494 ++++---- .../trader/monitoring/GCPauseMonitor.java | 321 +++-- .../trader/monitoring/SLAMonitorService.java | 128 +- .../trader/pressure/AllocationMode.java | 111 +- .../pressure/MemoryPressureService.java | 674 +++++------ .../payara/trader/pressure/ScenarioType.java | 7 +- .../payara/trader/rest/ApplicationConfig.java | 3 +- .../payara/trader/rest/GCStatsResource.java | 207 ++-- .../trader/rest/MemoryPressureResource.java | 126 +- .../payara/trader/rest/StatusResource.java | 133 ++- .../websocket/MarketDataBroadcaster.java | 293 +++-- .../trader/websocket/MarketDataWebSocket.java | 79 +- .../payara/trader/BasicFunctionalityTest.java | 116 +- .../aeron/MarketDataFragmentHandlerTest.java | 262 ++-- .../concurrency/ConcurrencyConfigTest.java | 535 ++++----- .../VirtualThreadExecutorTest.java | 363 +++--- .../payara/trader/gc/GCStatsServiceTest.java | 204 ++-- .../fish/payara/trader/gc/GCStatsTest.java | 1052 ++++++++--------- .../monitoring/SLAMonitorServiceTest.java | 210 ++-- .../trader/pressure/AllocationModeTest.java | 197 ++- .../trader/rest/GCStatsResourceTest.java | 152 +-- .../rest/MemoryPressureResourceTest.java | 93 +- .../trader/rest/StatusResourceTest.java | 667 ++++++----- .../fish/payara/trader/utils/GCTestUtil.java | 310 +++-- .../websocket/MarketDataBroadcasterTest.java | 196 +-- 33 files changed, 4321 insertions(+), 4654 deletions(-) diff --git a/pom.xml b/pom.xml index ab96153..9f82248 100644 --- a/pom.xml +++ b/pom.xml @@ -324,10 +324,9 @@ 3.0.0 - - 1.17.0 - - + + ${project.basedir}/spotless/java-formatter.xml + diff --git a/src/main/java/fish/payara/resource/HelloWorldResource.java b/src/main/java/fish/payara/resource/HelloWorldResource.java index 83991fa..0a7c26b 100644 --- a/src/main/java/fish/payara/resource/HelloWorldResource.java +++ b/src/main/java/fish/payara/resource/HelloWorldResource.java @@ -19,37 +19,28 @@ @Path("hello") public class HelloWorldResource { - @Inject - @ConfigProperty(name = "defaultName", defaultValue = "world") - private String defaultName; + @Inject + @ConfigProperty(name = "defaultName", defaultValue = "world") + private String defaultName; - @GET - @Operation(summary = "Get a personalized greeting") - @APIResponses( - value = { - @APIResponse(responseCode = "200", description = "Successful operation"), - @APIResponse(responseCode = "400", description = "Invalid input") - }) - @Counted(name = "helloEndpointCount", description = "Count of calls to the hello endpoint") - @Timed(name = "helloEndpointTime", description = "Time taken to execute the hello endpoint") - @Timeout(3000) - @Retry(maxRetries = 3) - @Fallback(fallbackMethod = "fallbackMethod") - public Response hello( - @QueryParam("name") - @Parameter( - name = "name", - description = "Name to include in the greeting", - required = false, - example = "John") - String name) { - if ((name == null) || name.trim().isEmpty()) { - name = defaultName; + @GET + @Operation(summary = "Get a personalized greeting") + @APIResponses(value = {@APIResponse(responseCode = "200", description = "Successful operation"), + @APIResponse(responseCode = "400", description = "Invalid input")}) + @Counted(name = "helloEndpointCount", description = "Count of calls to the hello endpoint") + @Timed(name = "helloEndpointTime", description = "Time taken to execute the hello endpoint") + @Timeout(3000) + @Retry(maxRetries = 3) + @Fallback(fallbackMethod = "fallbackMethod") + public Response hello( + @QueryParam("name") @Parameter(name = "name", description = "Name to include in the greeting", required = false, example = "John") String name) { + if ((name == null) || name.trim().isEmpty()) { + name = defaultName; + } + return Response.ok(name).build(); } - return Response.ok(name).build(); - } - public Response fallbackMethod(@QueryParam("name") String name) { - return Response.ok("Fallback data").build(); - } + public Response fallbackMethod(@QueryParam("name") String name) { + return Response.ok("Fallback data").build(); + } } diff --git a/src/main/java/fish/payara/trader/aeron/AeronSubscriberBean.java b/src/main/java/fish/payara/trader/aeron/AeronSubscriberBean.java index a5335c0..3c0a36d 100644 --- a/src/main/java/fish/payara/trader/aeron/AeronSubscriberBean.java +++ b/src/main/java/fish/payara/trader/aeron/AeronSubscriberBean.java @@ -21,152 +21,137 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; /** - * Aeron Ingress Singleton Bean Launches an embedded MediaDriver and subscribes to market data - * stream. Uses SBE decoders for zero-copy message processing. Runs in a dedicated thread to - * continuously poll for messages. IMPORTANT: This must initialize BEFORE MarketDataPublisher + * Aeron Ingress Singleton Bean Launches an embedded MediaDriver and subscribes to market data stream. Uses SBE decoders for zero-copy message processing. Runs + * in a dedicated thread to continuously poll for messages. IMPORTANT: This must initialize BEFORE MarketDataPublisher */ @ApplicationScoped public class AeronSubscriberBean { - private static final Logger LOGGER = Logger.getLogger(AeronSubscriberBean.class.getName()); + private static final Logger LOGGER = Logger.getLogger(AeronSubscriberBean.class.getName()); - private static final String CHANNEL = "aeron:ipc"; - private static final int STREAM_ID = 1001; - private static final int FRAGMENT_LIMIT = 10; + private static final String CHANNEL = "aeron:ipc"; + private static final int STREAM_ID = 1001; + private static final int FRAGMENT_LIMIT = 10; - private MediaDriver mediaDriver; - private Aeron aeron; - private Subscription subscription; - private volatile boolean running = false; - private Future pollingFuture; + private MediaDriver mediaDriver; + private Aeron aeron; + private Subscription subscription; + private volatile boolean running = false; + private Future pollingFuture; - @Inject private MarketDataFragmentHandler fragmentHandler; + @Inject + private MarketDataFragmentHandler fragmentHandler; - @Inject @VirtualThreadExecutor private ManagedExecutorService managedExecutorService; + @Inject + @VirtualThreadExecutor + private ManagedExecutorService managedExecutorService; - @Inject - @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") - private String ingestionMode; + @Inject + @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") + private String ingestionMode; - void contextInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) { - managedExecutorService.submit(this::init); - } - - public void init() { - if ("DIRECT".equalsIgnoreCase(ingestionMode)) { - LOGGER.info("Running in DIRECT mode - Skipping Aeron/MediaDriver initialization."); - return; + void contextInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) { + managedExecutorService.submit(this::init); } - LOGGER.info("Initializing Aeron Subscriber Bean..."); - - try { - LOGGER.info("Launching embedded MediaDriver..."); - mediaDriver = - MediaDriver.launchEmbedded( - new MediaDriver.Context() - .threadingMode(ThreadingMode.SHARED) - .dirDeleteOnStart(true) - .dirDeleteOnShutdown(true)); - - LOGGER.info("MediaDriver launched at: " + mediaDriver.aeronDirectoryName()); - LOGGER.info("Connecting Aeron client..."); - aeron = - Aeron.connect( - new Aeron.Context() - .aeronDirectoryName(mediaDriver.aeronDirectoryName()) - .errorHandler(this::onError) - .availableImageHandler( - image -> LOGGER.info("Available image: " + image.sourceIdentity())) - .unavailableImageHandler( - image -> LOGGER.info("Unavailable image: " + image.sourceIdentity()))); - LOGGER.info("Adding subscription on channel: " + CHANNEL + ", stream: " + STREAM_ID); - subscription = aeron.addSubscription(CHANNEL, STREAM_ID); - startPolling(); - LOGGER.info("Aeron Subscriber Bean initialized successfully"); - - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Aeron Subscriber Bean", e); - cleanup(); - throw new RuntimeException("Failed to initialize Aeron", e); + public void init() { + if ("DIRECT".equalsIgnoreCase(ingestionMode)) { + LOGGER.info("Running in DIRECT mode - Skipping Aeron/MediaDriver initialization."); + return; + } + + LOGGER.info("Initializing Aeron Subscriber Bean..."); + + try { + LOGGER.info("Launching embedded MediaDriver..."); + mediaDriver = MediaDriver + .launchEmbedded(new MediaDriver.Context().threadingMode(ThreadingMode.SHARED).dirDeleteOnStart(true).dirDeleteOnShutdown(true)); + + LOGGER.info("MediaDriver launched at: " + mediaDriver.aeronDirectoryName()); + LOGGER.info("Connecting Aeron client..."); + aeron = Aeron.connect(new Aeron.Context().aeronDirectoryName(mediaDriver.aeronDirectoryName()) + .errorHandler(this::onError) + .availableImageHandler(image -> LOGGER.info("Available image: " + image.sourceIdentity())) + .unavailableImageHandler(image -> LOGGER.info("Unavailable image: " + image.sourceIdentity()))); + LOGGER.info("Adding subscription on channel: " + CHANNEL + ", stream: " + STREAM_ID); + subscription = aeron.addSubscription(CHANNEL, STREAM_ID); + startPolling(); + LOGGER.info("Aeron Subscriber Bean initialized successfully"); + + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to initialize Aeron Subscriber Bean", e); + cleanup(); + throw new RuntimeException("Failed to initialize Aeron", e); + } } - } - - /** Start background task to continuously poll for messages */ - private void startPolling() { - running = true; - pollingFuture = - managedExecutorService.submit( - () -> { - LOGGER.info("Aeron polling task started"); - - final IdleStrategy idleStrategy = - new BackoffIdleStrategy( - 100, - 10, - TimeUnit.MICROSECONDS.toNanos(1), - TimeUnit.MICROSECONDS.toNanos(100)); - - while (running && !Thread.currentThread().isInterrupted()) { + + /** Start background task to continuously poll for messages */ + private void startPolling() { + running = true; + pollingFuture = managedExecutorService.submit(() -> { + LOGGER.info("Aeron polling task started"); + + final IdleStrategy idleStrategy = new BackoffIdleStrategy(100, 10, TimeUnit.MICROSECONDS.toNanos(1), TimeUnit.MICROSECONDS.toNanos(100)); + + while (running && !Thread.currentThread().isInterrupted()) { try { - final int fragmentsRead = subscription.poll(fragmentHandler, FRAGMENT_LIMIT); + final int fragmentsRead = subscription.poll(fragmentHandler, FRAGMENT_LIMIT); - idleStrategy.idle(fragmentsRead); + idleStrategy.idle(fragmentsRead); } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Error polling subscription", e); + LOGGER.log(Level.SEVERE, "Error polling subscription", e); } - } + } + + LOGGER.info("Aeron polling task stopped"); + }); + } - LOGGER.info("Aeron polling task stopped"); - }); - } + /** Error handler for Aeron */ + private void onError(Throwable throwable) { + LOGGER.log(Level.SEVERE, "Aeron error occurred", throwable); + } - /** Error handler for Aeron */ - private void onError(Throwable throwable) { - LOGGER.log(Level.SEVERE, "Aeron error occurred", throwable); - } + @PreDestroy + public void shutdown() { + LOGGER.info("Shutting down Aeron Subscriber Bean..."); + running = false; - @PreDestroy - public void shutdown() { - LOGGER.info("Shutting down Aeron Subscriber Bean..."); - running = false; + if (pollingFuture != null) { + pollingFuture.cancel(true); + } - if (pollingFuture != null) { - pollingFuture.cancel(true); + cleanup(); + LOGGER.info("Aeron Subscriber Bean shut down"); } - cleanup(); - LOGGER.info("Aeron Subscriber Bean shut down"); - } - - /** Clean up all Aeron resources */ - private void cleanup() { - CloseHelper.quietClose(subscription); - CloseHelper.quietClose(aeron); - CloseHelper.quietClose(mediaDriver); - } - - /** Get subscription statistics */ - public String getStatus() { - if (subscription != null) { - return String.format( - "Channel: %s, Stream: %d, Images: %d, Running: %b", - subscription.channel(), subscription.streamId(), subscription.imageCount(), running); + /** Clean up all Aeron resources */ + private void cleanup() { + CloseHelper.quietClose(subscription); + CloseHelper.quietClose(aeron); + CloseHelper.quietClose(mediaDriver); } - return "Not initialized"; - } - /** Get the Aeron directory name for connecting publishers */ - public String getAeronDirectoryName() { - if (mediaDriver != null) { - return mediaDriver.aeronDirectoryName(); + /** Get subscription statistics */ + public String getStatus() { + if (subscription != null) { + return String.format("Channel: %s, Stream: %d, Images: %d, Running: %b", subscription.channel(), subscription.streamId(), subscription.imageCount(), + running); + } + return "Not initialized"; } - return null; - } - /** Check if the MediaDriver is ready */ - public boolean isReady() { - return mediaDriver != null && aeron != null && subscription != null && running; - } + /** Get the Aeron directory name for connecting publishers */ + public String getAeronDirectoryName() { + if (mediaDriver != null) { + return mediaDriver.aeronDirectoryName(); + } + return null; + } + + /** Check if the MediaDriver is ready */ + public boolean isReady() { + return mediaDriver != null && aeron != null && subscription != null && running; + } } diff --git a/src/main/java/fish/payara/trader/aeron/MarketDataFragmentHandler.java b/src/main/java/fish/payara/trader/aeron/MarketDataFragmentHandler.java index d0ea6a6..8ec3125 100644 --- a/src/main/java/fish/payara/trader/aeron/MarketDataFragmentHandler.java +++ b/src/main/java/fish/payara/trader/aeron/MarketDataFragmentHandler.java @@ -11,300 +11,280 @@ import org.agrona.DirectBuffer; /** - * FragmentHandler that uses SBE Flyweights for zero-copy message decoding. This handler processes - * Aeron fragments by: 1. Decoding the SBE message header to identify message type 2. Using the - * appropriate SBE decoder (flyweight pattern) 3. Extracting data without object allocation 4. - * Broadcasting as JSON (intentionally creating garbage for GC stress testing) + * FragmentHandler that uses SBE Flyweights for zero-copy message decoding. This handler processes Aeron fragments by: 1. Decoding the SBE message header to + * identify message type 2. Using the appropriate SBE decoder (flyweight pattern) 3. Extracting data without object allocation 4. Broadcasting as JSON + * (intentionally creating garbage for GC stress testing) */ @ApplicationScoped public class MarketDataFragmentHandler implements FragmentHandler { - private static final Logger LOGGER = Logger.getLogger(MarketDataFragmentHandler.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MarketDataFragmentHandler.class.getName()); - private final MessageHeaderDecoder headerDecoder = new MessageHeaderDecoder(); + private final MessageHeaderDecoder headerDecoder = new MessageHeaderDecoder(); - private final TradeDecoder tradeDecoder = new TradeDecoder(); - private final QuoteDecoder quoteDecoder = new QuoteDecoder(); - private final MarketDepthDecoder marketDepthDecoder = new MarketDepthDecoder(); - private final OrderAckDecoder orderAckDecoder = new OrderAckDecoder(); - private final HeartbeatDecoder heartbeatDecoder = new HeartbeatDecoder(); + private final TradeDecoder tradeDecoder = new TradeDecoder(); + private final QuoteDecoder quoteDecoder = new QuoteDecoder(); + private final MarketDepthDecoder marketDepthDecoder = new MarketDepthDecoder(); + private final OrderAckDecoder orderAckDecoder = new OrderAckDecoder(); + private final HeartbeatDecoder heartbeatDecoder = new HeartbeatDecoder(); - private long messagesProcessed = 0; - private long messagesBroadcast = 0; - private long lastLogTime = System.currentTimeMillis(); + private long messagesProcessed = 0; + private long messagesBroadcast = 0; + private long lastLogTime = System.currentTimeMillis(); - private static final int SAMPLE_RATE = 50; - private long sampleCounter = 0; + private static final int SAMPLE_RATE = 50; + private long sampleCounter = 0; - @Inject MarketDataBroadcaster broadcaster; + @Inject + MarketDataBroadcaster broadcaster; - private final byte[] symbolBuffer = new byte[128]; - private final StringBuilder sb = new StringBuilder(1024); + private final byte[] symbolBuffer = new byte[128]; + private final StringBuilder sb = new StringBuilder(1024); - @Override - public void onFragment(DirectBuffer buffer, int offset, int length, Header header) { - try { - headerDecoder.wrap(buffer, offset); + @Override + public void onFragment(DirectBuffer buffer, int offset, int length, Header header) { + try { + headerDecoder.wrap(buffer, offset); - final int templateId = headerDecoder.templateId(); - final int actingBlockLength = headerDecoder.blockLength(); - final int actingVersion = headerDecoder.version(); + final int templateId = headerDecoder.templateId(); + final int actingBlockLength = headerDecoder.blockLength(); + final int actingVersion = headerDecoder.version(); - offset += headerDecoder.encodedLength(); + offset += headerDecoder.encodedLength(); - sampleCounter++; - final boolean shouldBroadcast = (sampleCounter % SAMPLE_RATE == 0); + sampleCounter++; + final boolean shouldBroadcast = (sampleCounter % SAMPLE_RATE == 0); - switch (templateId) { - case TradeDecoder.TEMPLATE_ID: - processTrade(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); - break; + switch (templateId) { + case TradeDecoder.TEMPLATE_ID : + processTrade(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); + break; - case QuoteDecoder.TEMPLATE_ID: - processQuote(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); - break; + case QuoteDecoder.TEMPLATE_ID : + processQuote(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); + break; - case MarketDepthDecoder.TEMPLATE_ID: - processMarketDepth(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); - break; + case MarketDepthDecoder.TEMPLATE_ID : + processMarketDepth(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); + break; - case OrderAckDecoder.TEMPLATE_ID: - processOrderAck(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); - break; + case OrderAckDecoder.TEMPLATE_ID : + processOrderAck(buffer, offset, actingBlockLength, actingVersion, shouldBroadcast); + break; - case HeartbeatDecoder.TEMPLATE_ID: - processHeartbeat(buffer, offset, actingBlockLength, actingVersion); - break; + case HeartbeatDecoder.TEMPLATE_ID : + processHeartbeat(buffer, offset, actingBlockLength, actingVersion); + break; - default: - LOGGER.warning("Unknown message template ID: " + templateId); - } + default : + LOGGER.warning("Unknown message template ID: " + templateId); + } - messagesProcessed++; - if (shouldBroadcast) { - messagesBroadcast++; - } - logStatistics(); + messagesProcessed++; + if (shouldBroadcast) { + messagesBroadcast++; + } + logStatistics(); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Error processing fragment", e); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error processing fragment", e); + } } - } - /** Process Trade message using SBE decoder (zero-copy) */ - private void processTrade( - DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { - if (!shouldBroadcast) { - return; + /** Process Trade message using SBE decoder (zero-copy) */ + private void processTrade(DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { + if (!shouldBroadcast) { + return; + } + + tradeDecoder.wrap(buffer, offset, blockLength, version); + + final long timestamp = tradeDecoder.timestamp(); + final long tradeId = tradeDecoder.tradeId(); + final long price = tradeDecoder.price(); + final long quantity = tradeDecoder.quantity(); + final Side side = tradeDecoder.side(); + + final int symbolLength = tradeDecoder.symbolLength(); + tradeDecoder.getSymbol(symbolBuffer, 0, symbolLength); + final String symbol = new String(symbolBuffer, 0, symbolLength); + + sb.setLength(0); + sb.append("{\"type\":\"trade\",\"timestamp\":") + .append(timestamp) + .append(",\"tradeId\":") + .append(tradeId) + .append(",\"symbol\":\"") + .append(symbol) + .append("\"") + .append(",\"price\":") + .append(price / 10000.0) + .append(",\"quantity\":") + .append(quantity) + .append(",\"side\":\"") + .append(side) + .append("\"}"); + + broadcaster.broadcast(sb.toString()); } - tradeDecoder.wrap(buffer, offset, blockLength, version); - - final long timestamp = tradeDecoder.timestamp(); - final long tradeId = tradeDecoder.tradeId(); - final long price = tradeDecoder.price(); - final long quantity = tradeDecoder.quantity(); - final Side side = tradeDecoder.side(); - - final int symbolLength = tradeDecoder.symbolLength(); - tradeDecoder.getSymbol(symbolBuffer, 0, symbolLength); - final String symbol = new String(symbolBuffer, 0, symbolLength); - - sb.setLength(0); - sb.append("{\"type\":\"trade\",\"timestamp\":") - .append(timestamp) - .append(",\"tradeId\":") - .append(tradeId) - .append(",\"symbol\":\"") - .append(symbol) - .append("\"") - .append(",\"price\":") - .append(price / 10000.0) - .append(",\"quantity\":") - .append(quantity) - .append(",\"side\":\"") - .append(side) - .append("\"}"); - - broadcaster.broadcast(sb.toString()); - } - - /** Process Quote message using SBE decoder (zero-copy) */ - private void processQuote( - DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { - if (!shouldBroadcast) { - return; + /** Process Quote message using SBE decoder (zero-copy) */ + private void processQuote(DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { + if (!shouldBroadcast) { + return; + } + + quoteDecoder.wrap(buffer, offset, blockLength, version); + + final long timestamp = quoteDecoder.timestamp(); + final long bidPrice = quoteDecoder.bidPrice(); + final long bidSize = quoteDecoder.bidSize(); + final long askPrice = quoteDecoder.askPrice(); + final long askSize = quoteDecoder.askSize(); + + final int symbolLength = quoteDecoder.symbolLength(); + quoteDecoder.getSymbol(symbolBuffer, 0, symbolLength); + final String symbol = new String(symbolBuffer, 0, symbolLength); + + sb.setLength(0); + sb.append("{\"type\":\"quote\",\"timestamp\":") + .append(timestamp) + .append(",\"symbol\":\"") + .append(symbol) + .append("\"") + .append(",\"bid\":{\"price\":") + .append(bidPrice / 10000.0) + .append(",\"size\":") + .append(bidSize) + .append("}") + .append(",\"ask\":{\"price\":") + .append(askPrice / 10000.0) + .append(",\"size\":") + .append(askSize) + .append("}}"); + + broadcaster.broadcast(sb.toString()); } - quoteDecoder.wrap(buffer, offset, blockLength, version); - - final long timestamp = quoteDecoder.timestamp(); - final long bidPrice = quoteDecoder.bidPrice(); - final long bidSize = quoteDecoder.bidSize(); - final long askPrice = quoteDecoder.askPrice(); - final long askSize = quoteDecoder.askSize(); - - final int symbolLength = quoteDecoder.symbolLength(); - quoteDecoder.getSymbol(symbolBuffer, 0, symbolLength); - final String symbol = new String(symbolBuffer, 0, symbolLength); - - sb.setLength(0); - sb.append("{\"type\":\"quote\",\"timestamp\":") - .append(timestamp) - .append(",\"symbol\":\"") - .append(symbol) - .append("\"") - .append(",\"bid\":{\"price\":") - .append(bidPrice / 10000.0) - .append(",\"size\":") - .append(bidSize) - .append("}") - .append(",\"ask\":{\"price\":") - .append(askPrice / 10000.0) - .append(",\"size\":") - .append(askSize) - .append("}}"); - - broadcaster.broadcast(sb.toString()); - } - - /** Process MarketDepth message with repeating groups (zero-copy) */ - private void processMarketDepth( - DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { - if (!shouldBroadcast) { - return; + /** Process MarketDepth message with repeating groups (zero-copy) */ + private void processMarketDepth(DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { + if (!shouldBroadcast) { + return; + } + + marketDepthDecoder.wrap(buffer, offset, blockLength, version); + + final long timestamp = marketDepthDecoder.timestamp(); + final long sequenceNumber = marketDepthDecoder.sequenceNumber(); + + sb.setLength(0); + sb.append("{\"type\":\"depth\",\"timestamp\":").append(timestamp).append(",\"sequence\":").append(sequenceNumber).append(",\"bids\":["); + + MarketDepthDecoder.BidsDecoder bids = marketDepthDecoder.bids(); + int bidCount = 0; + while (bids.hasNext()) { + bids.next(); + if (bidCount > 0) + sb.append(","); + sb.append("{\"price\":").append(bids.price() / 10000.0).append(",\"quantity\":").append(bids.quantity()).append("}"); + bidCount++; + } + sb.append("],\"asks\":["); + + MarketDepthDecoder.AsksDecoder asks = marketDepthDecoder.asks(); + int askCount = 0; + while (asks.hasNext()) { + asks.next(); + if (askCount > 0) + sb.append(","); + sb.append("{\"price\":").append(asks.price() / 10000.0).append(",\"quantity\":").append(asks.quantity()).append("}"); + askCount++; + } + sb.append("]"); + + final int symbolLength = marketDepthDecoder.symbolLength(); + marketDepthDecoder.getSymbol(symbolBuffer, 0, symbolLength); + final String symbol = new String(symbolBuffer, 0, symbolLength); + + sb.append(",\"symbol\":\"").append(symbol).append("\"}"); + + broadcaster.broadcast(sb.toString()); } - marketDepthDecoder.wrap(buffer, offset, blockLength, version); - - final long timestamp = marketDepthDecoder.timestamp(); - final long sequenceNumber = marketDepthDecoder.sequenceNumber(); - - sb.setLength(0); - sb.append("{\"type\":\"depth\",\"timestamp\":") - .append(timestamp) - .append(",\"sequence\":") - .append(sequenceNumber) - .append(",\"bids\":["); - - MarketDepthDecoder.BidsDecoder bids = marketDepthDecoder.bids(); - int bidCount = 0; - while (bids.hasNext()) { - bids.next(); - if (bidCount > 0) sb.append(","); - sb.append("{\"price\":") - .append(bids.price() / 10000.0) - .append(",\"quantity\":") - .append(bids.quantity()) - .append("}"); - bidCount++; + private void processOrderAck(DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { + if (!shouldBroadcast) { + return; + } + + orderAckDecoder.wrap(buffer, offset, blockLength, version); + + final long timestamp = orderAckDecoder.timestamp(); + final long orderId = orderAckDecoder.orderId(); + final long clientOrderId = orderAckDecoder.clientOrderId(); + final Side side = orderAckDecoder.side(); + final OrderType orderType = orderAckDecoder.orderType(); + final long price = orderAckDecoder.price(); + final long quantity = orderAckDecoder.quantity(); + final ExecType execType = orderAckDecoder.execType(); + final long leavesQty = orderAckDecoder.leavesQty(); + final long cumQty = orderAckDecoder.cumQty(); + + final int symbolLength = orderAckDecoder.symbolLength(); + orderAckDecoder.getSymbol(symbolBuffer, 0, symbolLength); + final String symbol = new String(symbolBuffer, 0, symbolLength); + + sb.setLength(0); + sb.append("{\"type\":\"orderAck\",\"timestamp\":") + .append(timestamp) + .append(",\"orderId\":") + .append(orderId) + .append(",\"clientOrderId\":") + .append(clientOrderId) + .append(",\"symbol\":\"") + .append(symbol) + .append("\"") + .append(",\"side\":\"") + .append(side) + .append("\"") + .append(",\"orderType\":\"") + .append(orderType) + .append("\"") + .append(",\"price\":") + .append(price / 10000.0) + .append(",\"quantity\":") + .append(quantity) + .append(",\"execType\":\"") + .append(execType) + .append("\"") + .append(",\"leavesQty\":") + .append(leavesQty) + .append(",\"cumQty\":") + .append(cumQty) + .append("}"); + + broadcaster.broadcast(sb.toString()); } - sb.append("],\"asks\":["); - - MarketDepthDecoder.AsksDecoder asks = marketDepthDecoder.asks(); - int askCount = 0; - while (asks.hasNext()) { - asks.next(); - if (askCount > 0) sb.append(","); - sb.append("{\"price\":") - .append(asks.price() / 10000.0) - .append(",\"quantity\":") - .append(asks.quantity()) - .append("}"); - askCount++; - } - sb.append("]"); - - final int symbolLength = marketDepthDecoder.symbolLength(); - marketDepthDecoder.getSymbol(symbolBuffer, 0, symbolLength); - final String symbol = new String(symbolBuffer, 0, symbolLength); - sb.append(",\"symbol\":\"").append(symbol).append("\"}"); + private void processHeartbeat(DirectBuffer buffer, int offset, int blockLength, int version) { + heartbeatDecoder.wrap(buffer, offset, blockLength, version); - broadcaster.broadcast(sb.toString()); - } + final long timestamp = heartbeatDecoder.timestamp(); + final long sequenceNumber = heartbeatDecoder.sequenceNumber(); - private void processOrderAck( - DirectBuffer buffer, int offset, int blockLength, int version, boolean shouldBroadcast) { - if (!shouldBroadcast) { - return; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Heartbeat: timestamp=" + timestamp + ", seq=" + sequenceNumber); + } } - orderAckDecoder.wrap(buffer, offset, blockLength, version); - - final long timestamp = orderAckDecoder.timestamp(); - final long orderId = orderAckDecoder.orderId(); - final long clientOrderId = orderAckDecoder.clientOrderId(); - final Side side = orderAckDecoder.side(); - final OrderType orderType = orderAckDecoder.orderType(); - final long price = orderAckDecoder.price(); - final long quantity = orderAckDecoder.quantity(); - final ExecType execType = orderAckDecoder.execType(); - final long leavesQty = orderAckDecoder.leavesQty(); - final long cumQty = orderAckDecoder.cumQty(); - - final int symbolLength = orderAckDecoder.symbolLength(); - orderAckDecoder.getSymbol(symbolBuffer, 0, symbolLength); - final String symbol = new String(symbolBuffer, 0, symbolLength); - - sb.setLength(0); - sb.append("{\"type\":\"orderAck\",\"timestamp\":") - .append(timestamp) - .append(",\"orderId\":") - .append(orderId) - .append(",\"clientOrderId\":") - .append(clientOrderId) - .append(",\"symbol\":\"") - .append(symbol) - .append("\"") - .append(",\"side\":\"") - .append(side) - .append("\"") - .append(",\"orderType\":\"") - .append(orderType) - .append("\"") - .append(",\"price\":") - .append(price / 10000.0) - .append(",\"quantity\":") - .append(quantity) - .append(",\"execType\":\"") - .append(execType) - .append("\"") - .append(",\"leavesQty\":") - .append(leavesQty) - .append(",\"cumQty\":") - .append(cumQty) - .append("}"); - - broadcaster.broadcast(sb.toString()); - } - - private void processHeartbeat(DirectBuffer buffer, int offset, int blockLength, int version) { - heartbeatDecoder.wrap(buffer, offset, blockLength, version); - - final long timestamp = heartbeatDecoder.timestamp(); - final long sequenceNumber = heartbeatDecoder.sequenceNumber(); - - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("Heartbeat: timestamp=" + timestamp + ", seq=" + sequenceNumber); - } - } - - private void logStatistics() { - long now = System.currentTimeMillis(); - if (now - lastLogTime > 5000) { - double elapsedSeconds = (now - lastLogTime) / 1000.0; - LOGGER.info( - String.format( - "FragmentHandler Stats - Processed: %,d (%.0f msg/sec) | Broadcast to UI: %,d (%.0f msg/sec) | Sample rate: 1 in %d", - messagesProcessed, - messagesProcessed / elapsedSeconds, - messagesBroadcast, - messagesBroadcast / elapsedSeconds, - SAMPLE_RATE)); - lastLogTime = now; - messagesProcessed = 0; - messagesBroadcast = 0; + private void logStatistics() { + long now = System.currentTimeMillis(); + if (now - lastLogTime > 5000) { + double elapsedSeconds = (now - lastLogTime) / 1000.0; + LOGGER.info(String.format("FragmentHandler Stats - Processed: %,d (%.0f msg/sec) | Broadcast to UI: %,d (%.0f msg/sec) | Sample rate: 1 in %d", + messagesProcessed, messagesProcessed / elapsedSeconds, messagesBroadcast, messagesBroadcast / elapsedSeconds, SAMPLE_RATE)); + lastLogTime = now; + messagesProcessed = 0; + messagesBroadcast = 0; + } } - } } diff --git a/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java b/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java index b4c30b4..dd3dfd6 100644 --- a/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java +++ b/src/main/java/fish/payara/trader/aeron/MarketDataPublisher.java @@ -26,605 +26,546 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; /** - * Market Data Publisher Simulator Generates synthetic market data and publishes via Aeron using SBE - * encoding. This simulates a high-frequency data feed for testing the ingestion pipeline. - * IMPORTANT: Depends on AeronSubscriberBean to initialize first (provides MediaDriver) + * Market Data Publisher Simulator Generates synthetic market data and publishes via Aeron using SBE encoding. This simulates a high-frequency data feed for + * testing the ingestion pipeline. IMPORTANT: Depends on AeronSubscriberBean to initialize first (provides MediaDriver) */ @ApplicationScoped public class MarketDataPublisher { - private static final Logger LOGGER = Logger.getLogger(MarketDataPublisher.class.getName()); - - private static final String CHANNEL = "aeron:ipc"; - private static final int STREAM_ID = 1001; - private static final int BUFFER_SIZE = 4096; - private static final int SAMPLE_RATE = 50; // Broadcast 1 in 50 messages to prevent flooding - - private static final String[] SYMBOLS = { - "AAPL", "GOOGL", "MSFT", "AMZN", "TSLA", "NVDA", "META", "NFLX" - }; - - private Aeron aeron; - private Publication publication; - - // SBE encoders (reusable flyweights) - private final MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - private final TradeEncoder tradeEncoder = new TradeEncoder(); - private final QuoteEncoder quoteEncoder = new QuoteEncoder(); - private final MarketDepthEncoder marketDepthEncoder = new MarketDepthEncoder(); - private final HeartbeatEncoder heartbeatEncoder = new HeartbeatEncoder(); - - private UnsafeBuffer buffer; - - private final AtomicLong sequenceNumber = new AtomicLong(0); - private final AtomicLong tradeIdGenerator = new AtomicLong(1000); - - private final AtomicLong messagesPublished = new AtomicLong(0); - private final AtomicInteger consecutiveFailures = new AtomicInteger(0); - private static final int MAX_CONSECUTIVE_FAILURES = 50; - private long sampleCounter = 0; - private volatile boolean initialized = false; - private volatile boolean running = false; - private boolean isDirectMode; - private long lastWarningLogTime = 0; - private static final long WARNING_LOG_INTERVAL_MS = - 5000; // Log warnings at most once per 5 seconds - - private Future publisherFuture; - private Future statsFuture; - - @Inject private AeronSubscriberBean subscriberBean; - - @Inject - @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") - private String ingestionMode; - - @Inject - @ConfigProperty(name = "ENABLE_PUBLISHER", defaultValue = "true") - String enablePublisherEnv; - - @Inject private MarketDataBroadcaster broadcaster; - - @Inject private HazelcastInstance hazelcastInstance; - - @Inject @VirtualThreadExecutor private ManagedExecutorService managedExecutorService; - - // Cluster-wide message counter (shared across all instances) - private IAtomicLong clusterMessageCounter; - - void contextInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) { - // managedExecutorService.submit(this::init); - init(); - } - - public void init() { - // Initialize cluster-wide message counter on ALL instances (even non-publishers) - // This allows all instances to read the shared counter value via Hazelcast CP Subsystem - if (hazelcastInstance != null) { - try { - clusterMessageCounter = - hazelcastInstance.getCPSubsystem().getAtomicLong("cluster-message-count"); - LOGGER.info("Initialized cluster-wide message counter"); - } catch (Exception e) { - LOGGER.log( - Level.WARNING, - "Failed to initialize cluster message counter, using local counter only", - e); - } - } + private static final Logger LOGGER = Logger.getLogger(MarketDataPublisher.class.getName()); - // Check if publisher should be enabled on this instance - if (enablePublisherEnv != null && !"true".equalsIgnoreCase(enablePublisherEnv)) { - LOGGER.info( - "Market Data Publisher DISABLED on this instance (ENABLE_PUBLISHER=" - + enablePublisherEnv - + ")"); - LOGGER.info("This instance will only consume messages from the cluster topic via Hazelcast"); - return; - } + private static final String CHANNEL = "aeron:ipc"; + private static final int STREAM_ID = 1001; + private static final int BUFFER_SIZE = 4096; + private static final int SAMPLE_RATE = 50; // Broadcast 1 in 50 messages to prevent flooding + + private static final String[] SYMBOLS = {"AAPL", "GOOGL", "MSFT", "AMZN", "TSLA", "NVDA", "META", "NFLX"}; + + private Aeron aeron; + private Publication publication; + + // SBE encoders (reusable flyweights) + private final MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + private final TradeEncoder tradeEncoder = new TradeEncoder(); + private final QuoteEncoder quoteEncoder = new QuoteEncoder(); + private final MarketDepthEncoder marketDepthEncoder = new MarketDepthEncoder(); + private final HeartbeatEncoder heartbeatEncoder = new HeartbeatEncoder(); + + private UnsafeBuffer buffer; + + private final AtomicLong sequenceNumber = new AtomicLong(0); + private final AtomicLong tradeIdGenerator = new AtomicLong(1000); + + private final AtomicLong messagesPublished = new AtomicLong(0); + private final AtomicInteger consecutiveFailures = new AtomicInteger(0); + private static final int MAX_CONSECUTIVE_FAILURES = 50; + private long sampleCounter = 0; + private volatile boolean initialized = false; + private volatile boolean running = false; + private boolean isDirectMode; + private long lastWarningLogTime = 0; + private static final long WARNING_LOG_INTERVAL_MS = 5000; // Log warnings at most once per 5 seconds + + private Future publisherFuture; + private Future statsFuture; + + @Inject + private AeronSubscriberBean subscriberBean; + + @Inject + @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") + private String ingestionMode; + + @Inject + @ConfigProperty(name = "ENABLE_PUBLISHER", defaultValue = "true") + String enablePublisherEnv; - LOGGER.info( - "Initializing Market Data Publisher (ENABLE_PUBLISHER=" - + enablePublisherEnv - + "). Mode: " - + ingestionMode); + @Inject + private MarketDataBroadcaster broadcaster; - if ("DIRECT".equalsIgnoreCase(ingestionMode)) { - LOGGER.info("Running in DIRECT mode - Bypassing Aeron/SBE setup."); - initialized = true; - isDirectMode = true; + @Inject + private HazelcastInstance hazelcastInstance; - startPublishing(); - return; + @Inject + @VirtualThreadExecutor + private ManagedExecutorService managedExecutorService; + + // Cluster-wide message counter (shared across all instances) + private IAtomicLong clusterMessageCounter; + + void contextInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) { + // managedExecutorService.submit(this::init); + init(); } - // Initialize buffer only if in AERON mode - this.buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(BUFFER_SIZE)); - - try { - // Wait for AeronSubscriberBean to be ready (both observers fire at roughly same time) - LOGGER.info("Waiting for AeronSubscriberBean to be ready..."); - int waitAttempts = 0; - while (!subscriberBean.isReady() && waitAttempts < 60) { - Thread.sleep(500); - waitAttempts++; - } - - if (!subscriberBean.isReady()) { - LOGGER.severe("AeronSubscriberBean did not become ready in time"); - return; - } - - String aeronDir = subscriberBean.getAeronDirectoryName(); - LOGGER.info("Connecting to embedded MediaDriver at: " + aeronDir); - - aeron = - Aeron.connect( - new Aeron.Context() - .aeronDirectoryName(aeronDir) - .errorHandler( - throwable -> LOGGER.log(Level.SEVERE, "Aeron publisher error", throwable))); - - LOGGER.info("Connected to Aeron. Adding publication..."); - - publication = aeron.addPublication(CHANNEL, STREAM_ID); - - LOGGER.info("Waiting for subscriber to connect to publication..."); - int attempts = 0; - while (!publication.isConnected() && attempts < 20) { - Thread.sleep(500); - attempts++; - } - - if (publication.isConnected()) { - LOGGER.info("Market Data Publisher initialized successfully"); - initialized = true; - - startPublishing(); - } else { - LOGGER.warning("Publisher not connected after waiting"); - } - - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to initialize publisher", e); + public void init() { + // Initialize cluster-wide message counter on ALL instances (even non-publishers) + // This allows all instances to read the shared counter value via Hazelcast CP Subsystem + if (hazelcastInstance != null) { + try { + clusterMessageCounter = hazelcastInstance.getCPSubsystem().getAtomicLong("cluster-message-count"); + LOGGER.info("Initialized cluster-wide message counter"); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to initialize cluster message counter, using local counter only", e); + } + } + + // Check if publisher should be enabled on this instance + if (enablePublisherEnv != null && !"true".equalsIgnoreCase(enablePublisherEnv)) { + LOGGER.info("Market Data Publisher DISABLED on this instance (ENABLE_PUBLISHER=" + enablePublisherEnv + ")"); + LOGGER.info("This instance will only consume messages from the cluster topic via Hazelcast"); + return; + } + + LOGGER.info("Initializing Market Data Publisher (ENABLE_PUBLISHER=" + enablePublisherEnv + "). Mode: " + ingestionMode); + + if ("DIRECT".equalsIgnoreCase(ingestionMode)) { + LOGGER.info("Running in DIRECT mode - Bypassing Aeron/SBE setup."); + initialized = true; + isDirectMode = true; + + startPublishing(); + return; + } + + // Initialize buffer only if in AERON mode + this.buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(BUFFER_SIZE)); + + try { + // Wait for AeronSubscriberBean to be ready (both observers fire at roughly same time) + LOGGER.info("Waiting for AeronSubscriberBean to be ready..."); + int waitAttempts = 0; + while (!subscriberBean.isReady() && waitAttempts < 60) { + Thread.sleep(500); + waitAttempts++; + } + + if (!subscriberBean.isReady()) { + LOGGER.severe("AeronSubscriberBean did not become ready in time"); + return; + } + + String aeronDir = subscriberBean.getAeronDirectoryName(); + LOGGER.info("Connecting to embedded MediaDriver at: " + aeronDir); + + aeron = Aeron.connect(new Aeron.Context().aeronDirectoryName(aeronDir) + .errorHandler(throwable -> LOGGER.log(Level.SEVERE, "Aeron publisher error", throwable))); + + LOGGER.info("Connected to Aeron. Adding publication..."); + + publication = aeron.addPublication(CHANNEL, STREAM_ID); + + LOGGER.info("Waiting for subscriber to connect to publication..."); + int attempts = 0; + while (!publication.isConnected() && attempts < 20) { + Thread.sleep(500); + attempts++; + } + + if (publication.isConnected()) { + LOGGER.info("Market Data Publisher initialized successfully"); + initialized = true; + + startPublishing(); + } else { + LOGGER.warning("Publisher not connected after waiting"); + } + + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to initialize publisher", e); + } } - } - /** Start background thread to continuously publish market data at high throughput */ - private void startPublishing() { - running = true; - publisherFuture = - managedExecutorService.submit( - () -> { - LOGGER.info( - "Market data publisher task started - targeting 50k-100k messages/sec with burst patterns"); + /** Start background thread to continuously publish market data at high throughput */ + private void startPublishing() { + running = true; + publisherFuture = managedExecutorService.submit(() -> { + LOGGER.info("Market data publisher task started - targeting 50k-100k messages/sec with burst patterns"); - final int BASE_BURST_SIZE = 500; - final long PARK_NANOS = 5_000; // 5 microseconds base rate + final int BASE_BURST_SIZE = 500; + final long PARK_NANOS = 5_000; // 5 microseconds base rate - while (running && !Thread.currentThread().isInterrupted()) { + while (running && !Thread.currentThread().isInterrupted()) { try { - // Apply burst multiplier for realistic market spikes - int burstMultiplier = getBurstMultiplier(); - int adjustedBurstSize = BASE_BURST_SIZE * burstMultiplier; - - // Log burst transitions - if (burstMultiplier > 1) { - long secondOfMinute = (System.currentTimeMillis() / 1000) % 60; - if (secondOfMinute == 20 || secondOfMinute == 45) { - LOGGER.info("BURST MODE: " + burstMultiplier + "x allocation spike started"); + // Apply burst multiplier for realistic market spikes + int burstMultiplier = getBurstMultiplier(); + int adjustedBurstSize = BASE_BURST_SIZE * burstMultiplier; + + // Log burst transitions + if (burstMultiplier > 1) { + long secondOfMinute = (System.currentTimeMillis() / 1000) % 60; + if (secondOfMinute == 20 || secondOfMinute == 45) { + LOGGER.info("BURST MODE: " + burstMultiplier + "x allocation spike started"); + } } - } - for (int i = 0; i < adjustedBurstSize && running; i++) { - publishTrade(); - publishQuote(); - publishMarketDepth(); + for (int i = 0; i < adjustedBurstSize && running; i++) { + publishTrade(); + publishQuote(); + publishMarketDepth(); - if (i % 100 == 0) { - publishHeartbeat(); + if (i % 100 == 0) { + publishHeartbeat(); + } } - } - LockSupport.parkNanos(PARK_NANOS); + LockSupport.parkNanos(PARK_NANOS); } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Critical error in publisher loop", e); - // Brief pause on error, then continue - LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100)); + LOGGER.log(Level.SEVERE, "Critical error in publisher loop", e); + // Brief pause on error, then continue + LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100)); } - } + } - LOGGER.info("Market data publisher task stopped"); - }); + LOGGER.info("Market data publisher task stopped"); + }); - statsFuture = - managedExecutorService.submit( - () -> { - long lastCount = 0; - long lastTime = System.currentTimeMillis(); + statsFuture = managedExecutorService.submit(() -> { + long lastCount = 0; + long lastTime = System.currentTimeMillis(); - while (running && !Thread.currentThread().isInterrupted()) { + while (running && !Thread.currentThread().isInterrupted()) { try { - Thread.sleep(5000); - - long currentCount = messagesPublished.get(); - long currentTime = System.currentTimeMillis(); - long messagesSinceLastLog = currentCount - lastCount; - double elapsedSeconds = (currentTime - lastTime) / 1000.0; - double messagesPerSecond = messagesSinceLastLog / elapsedSeconds; - - int currentMultiplier = getBurstMultiplier(); - String burstStatus = - currentMultiplier > 1 ? " [BURST: " + currentMultiplier + "x]" : ""; - - LOGGER.info( - String.format( - "Publisher Stats - Total: %,d | Last 5s: %,d (%.0f msg/sec)%s", - currentCount, messagesSinceLastLog, messagesPerSecond, burstStatus)); - - String statsJson = - String.format( - "{\"type\":\"stats\",\"total\":%d,\"rate\":%.0f,\"burstMultiplier\":%d}", - currentCount, messagesPerSecond, currentMultiplier); - broadcaster.broadcast(statsJson); - - lastCount = currentCount; - lastTime = currentTime; + Thread.sleep(5000); + + long currentCount = messagesPublished.get(); + long currentTime = System.currentTimeMillis(); + long messagesSinceLastLog = currentCount - lastCount; + double elapsedSeconds = (currentTime - lastTime) / 1000.0; + double messagesPerSecond = messagesSinceLastLog / elapsedSeconds; + + int currentMultiplier = getBurstMultiplier(); + String burstStatus = currentMultiplier > 1 ? " [BURST: " + currentMultiplier + "x]" : ""; + + LOGGER.info(String.format("Publisher Stats - Total: %,d | Last 5s: %,d (%.0f msg/sec)%s", currentCount, messagesSinceLastLog, + messagesPerSecond, burstStatus)); + + String statsJson = String.format("{\"type\":\"stats\",\"total\":%d,\"rate\":%.0f,\"burstMultiplier\":%d}", currentCount, messagesPerSecond, + currentMultiplier); + broadcaster.broadcast(statsJson); + + lastCount = currentCount; + lastTime = currentTime; } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; + Thread.currentThread().interrupt(); + break; } - } - }); - } - - /** - * Calculate burst multiplier based on time pattern simulating market events - * - *

    Pattern (60-second cycle): - 00-20s: Normal trading (1x) - 20-25s: News event burst (5x - * allocation spike) - 25-45s: Normal trading (1x) - 45-50s: Market close spike (3x allocation) - - * 50-60s: Normal trading (1x) - */ - private int getBurstMultiplier() { - long secondOfMinute = (System.currentTimeMillis() / 1000) % 60; - - if (secondOfMinute >= 20 && secondOfMinute < 25) { - return 5; // News event - 5x burst - } else if (secondOfMinute >= 45 && secondOfMinute < 50) { - return 3; // Market close - 3x spike + } + }); } - return 1; // Normal - } - - /** Publish a Trade message */ - private void publishTrade() { - if (isDirectMode) { - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); // Use ThreadLocalRandom - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - final double price = 100.0 + currentRandom.nextDouble() * 400.0; - final int quantity = currentRandom.nextInt(1000) + 100; - final String side = currentRandom.nextBoolean() ? "BUY" : "SELL"; - - String json = - String.format( - "{\"type\":\"trade\",\"timestamp\":%d,\"tradeId\":%d,\"symbol\":\"%s\",\"price\":%.4f,\"quantity\":%d,\"side\":\"%s\"}", - System.currentTimeMillis(), - tradeIdGenerator.incrementAndGet(), - symbol, - price, - quantity, - side); - if (++sampleCounter % SAMPLE_RATE == 0) { - broadcaster.broadcastWithArtificialLoad(json); - } - messagesPublished.incrementAndGet(); - // Increment cluster-wide counter - if (clusterMessageCounter != null) { - try { - clusterMessageCounter.incrementAndGet(); - } catch (Exception e) { - // Ignore cluster counter errors, not critical + /** + * Calculate burst multiplier based on time pattern simulating market events + * + *

    + * Pattern (60-second cycle): - 00-20s: Normal trading (1x) - 20-25s: News event burst (5x allocation spike) - 25-45s: Normal trading (1x) - 45-50s: Market + * close spike (3x allocation) - 50-60s: Normal trading (1x) + */ + private int getBurstMultiplier() { + long secondOfMinute = (System.currentTimeMillis() / 1000) % 60; + + if (secondOfMinute >= 20 && secondOfMinute < 25) { + return 5; // News event - 5x burst + } else if (secondOfMinute >= 45 && secondOfMinute < 50) { + return 3; // Market close - 3x spike } - } - return; + + return 1; // Normal } - int bufferOffset = 0; - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - - headerEncoder - .wrap(buffer, bufferOffset) - .blockLength(tradeEncoder.sbeBlockLength()) - .templateId(tradeEncoder.sbeTemplateId()) - .schemaId(tradeEncoder.sbeSchemaId()) - .version(tradeEncoder.sbeSchemaVersion()); - - bufferOffset += headerEncoder.encodedLength(); - - tradeEncoder - .wrap(buffer, bufferOffset) - .timestamp(System.currentTimeMillis()) - .tradeId(tradeIdGenerator.incrementAndGet()) - .price((long) ((100.0 + currentRandom.nextDouble() * 400.0) * 10000)) // $100-$500 - .quantity(currentRandom.nextInt(1000) + 100) - .side(currentRandom.nextBoolean() ? Side.BUY : Side.SELL) - .symbol(symbol); - - final int length = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); - offer(buffer, 0, length, "Trade"); - } - - /** Publish a Quote message */ - private void publishQuote() { - if (isDirectMode) { - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; - final double bidPrice = basePrice - 0.01; - final double askPrice = basePrice + 0.01; - final int bidSize = currentRandom.nextInt(10000) + 100; - final int askSize = currentRandom.nextInt(10000) + 100; - - String json = - String.format( - "{\"type\":\"quote\",\"timestamp\":%d,\"symbol\":\"%s\",\"bid\":{\"price\":%.4f,\"size\":%d},\"ask\":{\"price\":%.4f,\"size\":%d}}", - System.currentTimeMillis(), symbol, bidPrice, bidSize, askPrice, askSize); - if (++sampleCounter % SAMPLE_RATE == 0) { - broadcaster.broadcastWithArtificialLoad(json); - } - messagesPublished.incrementAndGet(); - // Increment cluster-wide counter - if (clusterMessageCounter != null) { - try { - clusterMessageCounter.incrementAndGet(); - } catch (Exception e) { - // Ignore cluster counter errors, not critical + /** Publish a Trade message */ + private void publishTrade() { + if (isDirectMode) { + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); // Use ThreadLocalRandom + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + final double price = 100.0 + currentRandom.nextDouble() * 400.0; + final int quantity = currentRandom.nextInt(1000) + 100; + final String side = currentRandom.nextBoolean() ? "BUY" : "SELL"; + + String json = String.format("{\"type\":\"trade\",\"timestamp\":%d,\"tradeId\":%d,\"symbol\":\"%s\",\"price\":%.4f,\"quantity\":%d,\"side\":\"%s\"}", + System.currentTimeMillis(), tradeIdGenerator.incrementAndGet(), symbol, price, quantity, side); + if (++sampleCounter % SAMPLE_RATE == 0) { + broadcaster.broadcastWithArtificialLoad(json); + } + messagesPublished.incrementAndGet(); + // Increment cluster-wide counter + if (clusterMessageCounter != null) { + try { + clusterMessageCounter.incrementAndGet(); + } catch (Exception e) { + // Ignore cluster counter errors, not critical + } + } + return; } - } - return; + + int bufferOffset = 0; + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + + headerEncoder.wrap(buffer, bufferOffset) + .blockLength(tradeEncoder.sbeBlockLength()) + .templateId(tradeEncoder.sbeTemplateId()) + .schemaId(tradeEncoder.sbeSchemaId()) + .version(tradeEncoder.sbeSchemaVersion()); + + bufferOffset += headerEncoder.encodedLength(); + + tradeEncoder.wrap(buffer, bufferOffset) + .timestamp(System.currentTimeMillis()) + .tradeId(tradeIdGenerator.incrementAndGet()) + .price((long) ((100.0 + currentRandom.nextDouble() * 400.0) * 10000)) // $100-$500 + .quantity(currentRandom.nextInt(1000) + 100) + .side(currentRandom.nextBoolean() ? Side.BUY : Side.SELL) + .symbol(symbol); + + final int length = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); + offer(buffer, 0, length, "Trade"); } - int bufferOffset = 0; - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; - - headerEncoder - .wrap(buffer, bufferOffset) - .blockLength(quoteEncoder.sbeBlockLength()) - .templateId(quoteEncoder.sbeTemplateId()) - .schemaId(quoteEncoder.sbeSchemaId()) - .version(quoteEncoder.sbeSchemaVersion()); - - bufferOffset += headerEncoder.encodedLength(); - - quoteEncoder - .wrap(buffer, bufferOffset) - .timestamp(System.currentTimeMillis()) - .bidPrice((long) ((basePrice - 0.01) * 10000)) - .bidSize(currentRandom.nextInt(10000) + 100) - .askPrice((long) ((basePrice + 0.01) * 10000)) - .askSize(currentRandom.nextInt(10000) + 100) - .symbol(symbol); - - final int length = headerEncoder.encodedLength() + quoteEncoder.encodedLength(); - offer(buffer, 0, length, "Quote"); - } - - /** Publish a MarketDepth message */ - private void publishMarketDepth() { - if (isDirectMode) { - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; - final long timestamp = System.currentTimeMillis(); - final long seq = sequenceNumber.incrementAndGet(); - - StringBuilder bidsJson = new StringBuilder("["); - for (int i = 0; i < 5; i++) { - if (i > 0) bidsJson.append(","); - bidsJson.append( - String.format( - "{\"price\":%.4f,\"quantity\":%d}", - basePrice - (i + 1) * 0.01, currentRandom.nextInt(5000) + 100)); - } - bidsJson.append("]"); - - StringBuilder asksJson = new StringBuilder("["); - for (int i = 0; i < 5; i++) { - if (i > 0) asksJson.append(","); - asksJson.append( - String.format( - "{\"price\":%.4f,\"quantity\":%d}", - basePrice + (i + 1) * 0.01, currentRandom.nextInt(5000) + 100)); - } - asksJson.append("]"); - - String json = - String.format( - "{\"type\":\"depth\",\"timestamp\":%d,\"symbol\":\"%s\",\"sequence\":%d,\"bids\":%s,\"asks\":%s}", - timestamp, symbol, seq, bidsJson, asksJson); - if (++sampleCounter % SAMPLE_RATE == 0) { - broadcaster.broadcastWithArtificialLoad(json); - } - messagesPublished.incrementAndGet(); - // Increment cluster-wide counter - if (clusterMessageCounter != null) { - try { - clusterMessageCounter.incrementAndGet(); - } catch (Exception e) { - // Ignore cluster counter errors, not critical + /** Publish a Quote message */ + private void publishQuote() { + if (isDirectMode) { + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; + final double bidPrice = basePrice - 0.01; + final double askPrice = basePrice + 0.01; + final int bidSize = currentRandom.nextInt(10000) + 100; + final int askSize = currentRandom.nextInt(10000) + 100; + + String json = String.format( + "{\"type\":\"quote\",\"timestamp\":%d,\"symbol\":\"%s\",\"bid\":{\"price\":%.4f,\"size\":%d},\"ask\":{\"price\":%.4f,\"size\":%d}}", + System.currentTimeMillis(), symbol, bidPrice, bidSize, askPrice, askSize); + if (++sampleCounter % SAMPLE_RATE == 0) { + broadcaster.broadcastWithArtificialLoad(json); + } + messagesPublished.incrementAndGet(); + // Increment cluster-wide counter + if (clusterMessageCounter != null) { + try { + clusterMessageCounter.incrementAndGet(); + } catch (Exception e) { + // Ignore cluster counter errors, not critical + } + } + return; } - } - return; - } - int bufferOffset = 0; - final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); - final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; - final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; - - headerEncoder - .wrap(buffer, bufferOffset) - .blockLength(marketDepthEncoder.sbeBlockLength()) - .templateId(marketDepthEncoder.sbeTemplateId()) - .schemaId(marketDepthEncoder.sbeSchemaId()) - .version(marketDepthEncoder.sbeSchemaVersion()); - - bufferOffset += headerEncoder.encodedLength(); - - marketDepthEncoder - .wrap(buffer, bufferOffset) - .timestamp(System.currentTimeMillis()) - .sequenceNumber(sequenceNumber.incrementAndGet()); - - MarketDepthEncoder.BidsEncoder bidsEncoder = marketDepthEncoder.bidsCount(5); - for (int i = 0; i < 5; i++) { - bidsEncoder - .next() - .price((long) ((basePrice - (i + 1) * 0.01) * 10000)) - .quantity(currentRandom.nextInt(5000) + 100); + int bufferOffset = 0; + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; + + headerEncoder.wrap(buffer, bufferOffset) + .blockLength(quoteEncoder.sbeBlockLength()) + .templateId(quoteEncoder.sbeTemplateId()) + .schemaId(quoteEncoder.sbeSchemaId()) + .version(quoteEncoder.sbeSchemaVersion()); + + bufferOffset += headerEncoder.encodedLength(); + + quoteEncoder.wrap(buffer, bufferOffset) + .timestamp(System.currentTimeMillis()) + .bidPrice((long) ((basePrice - 0.01) * 10000)) + .bidSize(currentRandom.nextInt(10000) + 100) + .askPrice((long) ((basePrice + 0.01) * 10000)) + .askSize(currentRandom.nextInt(10000) + 100) + .symbol(symbol); + + final int length = headerEncoder.encodedLength() + quoteEncoder.encodedLength(); + offer(buffer, 0, length, "Quote"); } - MarketDepthEncoder.AsksEncoder asksEncoder = marketDepthEncoder.asksCount(5); - for (int i = 0; i < 5; i++) { - asksEncoder - .next() - .price((long) ((basePrice + (i + 1) * 0.01) * 10000)) - .quantity(currentRandom.nextInt(5000) + 100); - } + /** Publish a MarketDepth message */ + private void publishMarketDepth() { + if (isDirectMode) { + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; + final long timestamp = System.currentTimeMillis(); + final long seq = sequenceNumber.incrementAndGet(); + + StringBuilder bidsJson = new StringBuilder("["); + for (int i = 0; i < 5; i++) { + if (i > 0) + bidsJson.append(","); + bidsJson.append(String.format("{\"price\":%.4f,\"quantity\":%d}", basePrice - (i + 1) * 0.01, currentRandom.nextInt(5000) + 100)); + } + bidsJson.append("]"); + + StringBuilder asksJson = new StringBuilder("["); + for (int i = 0; i < 5; i++) { + if (i > 0) + asksJson.append(","); + asksJson.append(String.format("{\"price\":%.4f,\"quantity\":%d}", basePrice + (i + 1) * 0.01, currentRandom.nextInt(5000) + 100)); + } + asksJson.append("]"); + + String json = String.format("{\"type\":\"depth\",\"timestamp\":%d,\"symbol\":\"%s\",\"sequence\":%d,\"bids\":%s,\"asks\":%s}", timestamp, symbol, + seq, bidsJson, asksJson); + if (++sampleCounter % SAMPLE_RATE == 0) { + broadcaster.broadcastWithArtificialLoad(json); + } + messagesPublished.incrementAndGet(); + // Increment cluster-wide counter + if (clusterMessageCounter != null) { + try { + clusterMessageCounter.incrementAndGet(); + } catch (Exception e) { + // Ignore cluster counter errors, not critical + } + } + return; + } - marketDepthEncoder.symbol(symbol); + int bufferOffset = 0; + final ThreadLocalRandom currentRandom = ThreadLocalRandom.current(); + final String symbol = SYMBOLS[currentRandom.nextInt(SYMBOLS.length)]; + final double basePrice = 100.0 + currentRandom.nextDouble() * 400.0; - final int length = headerEncoder.encodedLength() + marketDepthEncoder.encodedLength(); - offer(buffer, 0, length, "MarketDepth"); - } + headerEncoder.wrap(buffer, bufferOffset) + .blockLength(marketDepthEncoder.sbeBlockLength()) + .templateId(marketDepthEncoder.sbeTemplateId()) + .schemaId(marketDepthEncoder.sbeSchemaId()) + .version(marketDepthEncoder.sbeSchemaVersion()); - /** Publish a Heartbeat message */ - private void publishHeartbeat() { - if (isDirectMode) { - // In DIRECT mode, we just increment counter but don't broadcast heartbeats to UI - // as they are mainly for system health checks in the Aeron log - messagesPublished.incrementAndGet(); - return; - } + bufferOffset += headerEncoder.encodedLength(); - int bufferOffset = 0; + marketDepthEncoder.wrap(buffer, bufferOffset).timestamp(System.currentTimeMillis()).sequenceNumber(sequenceNumber.incrementAndGet()); - headerEncoder - .wrap(buffer, bufferOffset) - .blockLength(heartbeatEncoder.sbeBlockLength()) - .templateId(heartbeatEncoder.sbeTemplateId()) - .schemaId(heartbeatEncoder.sbeSchemaId()) - .version(heartbeatEncoder.sbeSchemaVersion()); + MarketDepthEncoder.BidsEncoder bidsEncoder = marketDepthEncoder.bidsCount(5); + for (int i = 0; i < 5; i++) { + bidsEncoder.next().price((long) ((basePrice - (i + 1) * 0.01) * 10000)).quantity(currentRandom.nextInt(5000) + 100); + } - bufferOffset += headerEncoder.encodedLength(); + MarketDepthEncoder.AsksEncoder asksEncoder = marketDepthEncoder.asksCount(5); + for (int i = 0; i < 5; i++) { + asksEncoder.next().price((long) ((basePrice + (i + 1) * 0.01) * 10000)).quantity(currentRandom.nextInt(5000) + 100); + } - heartbeatEncoder - .wrap(buffer, bufferOffset) - .timestamp(System.currentTimeMillis()) - .sequenceNumber(sequenceNumber.get()); + marketDepthEncoder.symbol(symbol); - final int length = headerEncoder.encodedLength() + heartbeatEncoder.encodedLength(); - offer(buffer, 0, length, "Heartbeat"); - } + final int length = headerEncoder.encodedLength() + marketDepthEncoder.encodedLength(); + offer(buffer, 0, length, "MarketDepth"); + } - /** Offer buffer to Aeron publication with retry logic */ - private void offer(UnsafeBuffer buffer, int offset, int length, String messageType) { - long result; - int retries = 3; + /** Publish a Heartbeat message */ + private void publishHeartbeat() { + if (isDirectMode) { + // In DIRECT mode, we just increment counter but don't broadcast heartbeats to UI + // as they are mainly for system health checks in the Aeron log + messagesPublished.incrementAndGet(); + return; + } - while (retries > 0) { - result = publication.offer(buffer, offset, length); + int bufferOffset = 0; - if (result > 0) { - messagesPublished.incrementAndGet(); - // Increment cluster-wide counter - if (clusterMessageCounter != null) { - try { - clusterMessageCounter.incrementAndGet(); - } catch (Exception e) { - // Ignore cluster counter errors, not critical - } + headerEncoder.wrap(buffer, bufferOffset) + .blockLength(heartbeatEncoder.sbeBlockLength()) + .templateId(heartbeatEncoder.sbeTemplateId()) + .schemaId(heartbeatEncoder.sbeSchemaId()) + .version(heartbeatEncoder.sbeSchemaVersion()); + + bufferOffset += headerEncoder.encodedLength(); + + heartbeatEncoder.wrap(buffer, bufferOffset).timestamp(System.currentTimeMillis()).sequenceNumber(sequenceNumber.get()); + + final int length = headerEncoder.encodedLength() + heartbeatEncoder.encodedLength(); + offer(buffer, 0, length, "Heartbeat"); + } + + /** Offer buffer to Aeron publication with retry logic */ + private void offer(UnsafeBuffer buffer, int offset, int length, String messageType) { + long result; + int retries = 3; + + while (retries > 0) { + result = publication.offer(buffer, offset, length); + + if (result > 0) { + messagesPublished.incrementAndGet(); + // Increment cluster-wide counter + if (clusterMessageCounter != null) { + try { + clusterMessageCounter.incrementAndGet(); + } catch (Exception e) { + // Ignore cluster counter errors, not critical + } + } + consecutiveFailures.set(0); + return; + } else if (result == Publication.BACK_PRESSURED) { + continue; + } else if (result == Publication.NOT_CONNECTED) { + logWarningRateLimited("Publication not connected"); + handlePublishFailure(messageType); + return; + } else { + logWarningRateLimited("Offer failed for " + messageType + ": " + result); + handlePublishFailure(messageType); + return; + } } - consecutiveFailures.set(0); - return; - } else if (result == Publication.BACK_PRESSURED) { - continue; - } else if (result == Publication.NOT_CONNECTED) { - logWarningRateLimited("Publication not connected"); - handlePublishFailure(messageType); - return; - } else { - logWarningRateLimited("Offer failed for " + messageType + ": " + result); + + logWarningRateLimited("Failed to publish " + messageType + " after retries"); handlePublishFailure(messageType); - return; - } } - logWarningRateLimited("Failed to publish " + messageType + " after retries"); - handlePublishFailure(messageType); - } - - private void logWarningRateLimited(String message) { - long now = System.currentTimeMillis(); - if (now - lastWarningLogTime >= WARNING_LOG_INTERVAL_MS) { - LOGGER.warning(message); - lastWarningLogTime = now; + private void logWarningRateLimited(String message) { + long now = System.currentTimeMillis(); + if (now - lastWarningLogTime >= WARNING_LOG_INTERVAL_MS) { + LOGGER.warning(message); + lastWarningLogTime = now; + } } - } - - private void handlePublishFailure(String messageType) { - int failures = consecutiveFailures.incrementAndGet(); - if (failures >= MAX_CONSECUTIVE_FAILURES) { - LOGGER.severe( - String.format( - "Circuit breaker triggered: %d consecutive publish failures (last attempted: %s). Stopping message generation.", - failures, messageType)); - running = false; + + private void handlePublishFailure(String messageType) { + int failures = consecutiveFailures.incrementAndGet(); + if (failures >= MAX_CONSECUTIVE_FAILURES) { + LOGGER.severe(String.format("Circuit breaker triggered: %d consecutive publish failures (last attempted: %s). Stopping message generation.", + failures, messageType)); + running = false; + } } - } - @PreDestroy - public void shutdown() { - LOGGER.info("Shutting down Market Data Publisher..."); + @PreDestroy + public void shutdown() { + LOGGER.info("Shutting down Market Data Publisher..."); - running = false; + running = false; - if (publisherFuture != null) { - publisherFuture.cancel(true); - } + if (publisherFuture != null) { + publisherFuture.cancel(true); + } - if (statsFuture != null) { - statsFuture.cancel(true); - } + if (statsFuture != null) { + statsFuture.cancel(true); + } - if (publication != null) { - publication.close(); + if (publication != null) { + publication.close(); + } + if (aeron != null) { + aeron.close(); + } + + LOGGER.info("Market Data Publisher shut down. Total messages published: " + messagesPublished.get()); } - if (aeron != null) { - aeron.close(); + + public long getMessagesPublished() { + return messagesPublished.get(); } - LOGGER.info( - "Market Data Publisher shut down. Total messages published: " + messagesPublished.get()); - } - - public long getMessagesPublished() { - return messagesPublished.get(); - } - - public long getClusterMessagesPublished() { - if (clusterMessageCounter != null) { - try { - return clusterMessageCounter.get(); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to read cluster message counter", e); - } + public long getClusterMessagesPublished() { + if (clusterMessageCounter != null) { + try { + return clusterMessageCounter.get(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to read cluster message counter", e); + } + } + return 0; } - return 0; - } } diff --git a/src/main/java/fish/payara/trader/concurrency/ConcurrencyConfig.java b/src/main/java/fish/payara/trader/concurrency/ConcurrencyConfig.java index 1317877..caab85b 100644 --- a/src/main/java/fish/payara/trader/concurrency/ConcurrencyConfig.java +++ b/src/main/java/fish/payara/trader/concurrency/ConcurrencyConfig.java @@ -4,12 +4,9 @@ import jakarta.enterprise.context.ApplicationScoped; /** - * Configuration for Jakarta Concurrency resources. Defines a ManagedExecutorService that uses - * Virtual Threads (Project Loom). + * Configuration for Jakarta Concurrency resources. Defines a ManagedExecutorService that uses Virtual Threads (Project Loom). */ @ApplicationScoped -@ManagedExecutorDefinition( - name = "java:module/concurrent/VirtualThreadExecutor", - virtual = true, - qualifiers = {VirtualThreadExecutor.class}) -public class ConcurrencyConfig {} +@ManagedExecutorDefinition(name = "java:module/concurrent/VirtualThreadExecutor", virtual = true, qualifiers = {VirtualThreadExecutor.class}) +public class ConcurrencyConfig { +} diff --git a/src/main/java/fish/payara/trader/concurrency/VirtualThreadExecutor.java b/src/main/java/fish/payara/trader/concurrency/VirtualThreadExecutor.java index eb1d993..6cdf766 100644 --- a/src/main/java/fish/payara/trader/concurrency/VirtualThreadExecutor.java +++ b/src/main/java/fish/payara/trader/concurrency/VirtualThreadExecutor.java @@ -14,4 +14,5 @@ @Qualifier @Retention(RUNTIME) @Target({METHOD, FIELD, PARAMETER, TYPE}) -public @interface VirtualThreadExecutor {} +public @interface VirtualThreadExecutor { +} diff --git a/src/main/java/fish/payara/trader/gc/GCStats.java b/src/main/java/fish/payara/trader/gc/GCStats.java index c2da5d6..b0f07ff 100644 --- a/src/main/java/fish/payara/trader/gc/GCStats.java +++ b/src/main/java/fish/payara/trader/gc/GCStats.java @@ -4,154 +4,156 @@ import java.util.Map; public class GCStats { - private String gcName; - private long collectionCount; - private long collectionTime; - private long lastPauseDuration; - private List recentPauses; - private PausePercentiles percentiles; - private long totalMemory; - private long usedMemory; - private long freeMemory; - private Map phaseBreakdown; - - public static class PausePercentiles { - private long p50; - private long p95; - private long p99; - private long p999; - private long max; - - public PausePercentiles() {} - - public PausePercentiles(long p50, long p95, long p99, long p999, long max) { - this.p50 = p50; - this.p95 = p95; - this.p99 = p99; - this.p999 = p999; - this.max = max; + private String gcName; + private long collectionCount; + private long collectionTime; + private long lastPauseDuration; + private List recentPauses; + private PausePercentiles percentiles; + private long totalMemory; + private long usedMemory; + private long freeMemory; + private Map phaseBreakdown; + + public static class PausePercentiles { + private long p50; + private long p95; + private long p99; + private long p999; + private long max; + + public PausePercentiles() { + } + + public PausePercentiles(long p50, long p95, long p99, long p999, long max) { + this.p50 = p50; + this.p95 = p95; + this.p99 = p99; + this.p999 = p999; + this.max = max; + } + + public long getP50() { + return p50; + } + + public void setP50(long p50) { + this.p50 = p50; + } + + public long getP95() { + return p95; + } + + public void setP95(long p95) { + this.p95 = p95; + } + + public long getP99() { + return p99; + } + + public void setP99(long p99) { + this.p99 = p99; + } + + public long getP999() { + return p999; + } + + public void setP999(long p999) { + this.p999 = p999; + } + + public long getMax() { + return max; + } + + public void setMax(long max) { + this.max = max; + } } - public long getP50() { - return p50; + public GCStats() { } - public void setP50(long p50) { - this.p50 = p50; + public String getGcName() { + return gcName; } - public long getP95() { - return p95; + public void setGcName(String gcName) { + this.gcName = gcName; } - public void setP95(long p95) { - this.p95 = p95; + public long getCollectionCount() { + return collectionCount; } - public long getP99() { - return p99; + public void setCollectionCount(long collectionCount) { + this.collectionCount = collectionCount; } - public void setP99(long p99) { - this.p99 = p99; + public long getCollectionTime() { + return collectionTime; } - public long getP999() { - return p999; + public void setCollectionTime(long collectionTime) { + this.collectionTime = collectionTime; } - public void setP999(long p999) { - this.p999 = p999; + public long getLastPauseDuration() { + return lastPauseDuration; } - public long getMax() { - return max; + public void setLastPauseDuration(long lastPauseDuration) { + this.lastPauseDuration = lastPauseDuration; } - public void setMax(long max) { - this.max = max; + public List getRecentPauses() { + return recentPauses; } - } - - public GCStats() {} - - public String getGcName() { - return gcName; - } - - public void setGcName(String gcName) { - this.gcName = gcName; - } - - public long getCollectionCount() { - return collectionCount; - } - - public void setCollectionCount(long collectionCount) { - this.collectionCount = collectionCount; - } - - public long getCollectionTime() { - return collectionTime; - } - - public void setCollectionTime(long collectionTime) { - this.collectionTime = collectionTime; - } - - public long getLastPauseDuration() { - return lastPauseDuration; - } - - public void setLastPauseDuration(long lastPauseDuration) { - this.lastPauseDuration = lastPauseDuration; - } - public List getRecentPauses() { - return recentPauses; - } - - public void setRecentPauses(List recentPauses) { - this.recentPauses = recentPauses; - } + public void setRecentPauses(List recentPauses) { + this.recentPauses = recentPauses; + } - public PausePercentiles getPercentiles() { - return percentiles; - } + public PausePercentiles getPercentiles() { + return percentiles; + } - public void setPercentiles(PausePercentiles percentiles) { - this.percentiles = percentiles; - } + public void setPercentiles(PausePercentiles percentiles) { + this.percentiles = percentiles; + } - public long getTotalMemory() { - return totalMemory; - } + public long getTotalMemory() { + return totalMemory; + } - public void setTotalMemory(long totalMemory) { - this.totalMemory = totalMemory; - } + public void setTotalMemory(long totalMemory) { + this.totalMemory = totalMemory; + } - public long getUsedMemory() { - return usedMemory; - } + public long getUsedMemory() { + return usedMemory; + } - public void setUsedMemory(long usedMemory) { - this.usedMemory = usedMemory; - } + public void setUsedMemory(long usedMemory) { + this.usedMemory = usedMemory; + } - public long getFreeMemory() { - return freeMemory; - } + public long getFreeMemory() { + return freeMemory; + } - public void setFreeMemory(long freeMemory) { - this.freeMemory = freeMemory; - } + public void setFreeMemory(long freeMemory) { + this.freeMemory = freeMemory; + } - public Map getPhaseBreakdown() { - return phaseBreakdown; - } + public Map getPhaseBreakdown() { + return phaseBreakdown; + } - public void setPhaseBreakdown(Map phaseBreakdown) { - this.phaseBreakdown = phaseBreakdown; - } + public void setPhaseBreakdown(Map phaseBreakdown) { + this.phaseBreakdown = phaseBreakdown; + } } diff --git a/src/main/java/fish/payara/trader/gc/GCStatsService.java b/src/main/java/fish/payara/trader/gc/GCStatsService.java index 74064bc..e4a3368 100644 --- a/src/main/java/fish/payara/trader/gc/GCStatsService.java +++ b/src/main/java/fish/payara/trader/gc/GCStatsService.java @@ -20,288 +20,270 @@ @ApplicationScoped public class GCStatsService implements NotificationListener { - private static final Logger LOGGER = Logger.getLogger(GCStatsService.class.getName()); - private static final int MAX_PAUSE_HISTORY = 1000; - - private final Map> pauseHistory = new HashMap<>(); - private final Map> phaseHistory = new HashMap<>(); - - /** - * Breakdown of GC pause into constituent phases (e.g., Mark, Relocate, Evacuate). - * - *

    Not all JVMs expose detailed phase information via GcInfo. When unavailable, the breakdown - * will contain only a "Total" phase with the full pause duration. This is a best-effort - * extraction that varies by GC implementation (G1, C4, ZGC, etc.). - */ - public static class GCPhaseBreakdown { - public final long totalDurationMs; - public final Map phaseDurationsMs; - public final long timestamp; - - public GCPhaseBreakdown( - long totalDurationMs, Map phaseDurationsMs, long timestamp) { - this.totalDurationMs = totalDurationMs; - this.phaseDurationsMs = Map.copyOf(phaseDurationsMs); // Immutable copy - this.timestamp = timestamp; + private static final Logger LOGGER = Logger.getLogger(GCStatsService.class.getName()); + private static final int MAX_PAUSE_HISTORY = 1000; + + private final Map> pauseHistory = new HashMap<>(); + private final Map> phaseHistory = new HashMap<>(); + + /** + * Breakdown of GC pause into constituent phases (e.g., Mark, Relocate, Evacuate). + * + *

    + * Not all JVMs expose detailed phase information via GcInfo. When unavailable, the breakdown will contain only a "Total" phase with the full pause + * duration. This is a best-effort extraction that varies by GC implementation (G1, C4, ZGC, etc.). + */ + public static class GCPhaseBreakdown { + public final long totalDurationMs; + public final Map phaseDurationsMs; + public final long timestamp; + + public GCPhaseBreakdown(long totalDurationMs, Map phaseDurationsMs, long timestamp) { + this.totalDurationMs = totalDurationMs; + this.phaseDurationsMs = Map.copyOf(phaseDurationsMs); // Immutable copy + this.timestamp = timestamp; + } } - } - - /** - * Statistics for a single GC phase across multiple collections. - * - *

    Provides percentile distribution of phase durations to identify which phases dominate pause - * times. - */ - public static class PhaseStats { - public final String phaseName; - public final long count; - public final long p50Ms; - public final long p95Ms; - public final long p99Ms; - public final long maxMs; - - public PhaseStats( - String phaseName, long count, long p50Ms, long p95Ms, long p99Ms, long maxMs) { - this.phaseName = phaseName; - this.count = count; - this.p50Ms = p50Ms; - this.p95Ms = p95Ms; - this.p99Ms = p99Ms; - this.maxMs = maxMs; + + /** + * Statistics for a single GC phase across multiple collections. + * + *

    + * Provides percentile distribution of phase durations to identify which phases dominate pause times. + */ + public static class PhaseStats { + public final String phaseName; + public final long count; + public final long p50Ms; + public final long p95Ms; + public final long p99Ms; + public final long maxMs; + + public PhaseStats(String phaseName, long count, long p50Ms, long p95Ms, long p99Ms, long maxMs) { + this.phaseName = phaseName; + this.count = count; + this.p50Ms = p50Ms; + this.p95Ms = p95Ms; + this.p99Ms = p99Ms; + this.maxMs = maxMs; + } } - } - - @PostConstruct - public void init() { - LOGGER.info("Initializing GC Notification Listener..."); - List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); - for (GarbageCollectorMXBean gcBean : gcBeans) { - LOGGER.info("Registering listener for GC Bean: " + gcBean.getName()); - if (gcBean instanceof NotificationEmitter) { - ((NotificationEmitter) gcBean).addNotificationListener(this, null, null); - } + + @PostConstruct + public void init() { + LOGGER.info("Initializing GC Notification Listener..."); + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean gcBean : gcBeans) { + LOGGER.info("Registering listener for GC Bean: " + gcBean.getName()); + if (gcBean instanceof NotificationEmitter) { + ((NotificationEmitter) gcBean).addNotificationListener(this, null, null); + } + } } - } - - @Override - public void handleNotification(Notification notification, Object handback) { - if (notification - .getType() - .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { - GarbageCollectionNotificationInfo info = - GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); - - String gcName = info.getGcName(); - String gcAction = info.getGcAction(); - String gcCause = info.getGcCause(); - GcInfo gcInfo = info.getGcInfo(); - long duration = gcInfo.getDuration(); - - // FILTERING LOGIC: - // Azul C4 exposes "GPGC" (Concurrent Cycle) and "GPGC Pauses" (STW Pauses). - // We MUST ignore "GPGC" because it reports cycle time (hundreds of ms) which is NOT a pause. - if ("GPGC".equals(gcName)) { - return; - } - - // Also ignore other known concurrent cycle beans if they appear - if (gcName.contains("Cycles") && !gcName.contains("Pauses")) { - return; - } - - // Pause duration history (existing logic) - ConcurrentLinkedDeque history = - pauseHistory.computeIfAbsent(gcName, k -> new ConcurrentLinkedDeque<>()); - history.addLast(duration); - while (history.size() > MAX_PAUSE_HISTORY) { - history.removeFirst(); - } - - // Phase breakdown extraction (new logic) - Map phaseTimes = extractPhaseTimes(gcInfo, gcName, gcAction); - GCPhaseBreakdown breakdown = - new GCPhaseBreakdown(duration, phaseTimes, System.currentTimeMillis()); - - ConcurrentLinkedDeque phaseHist = - phaseHistory.computeIfAbsent(gcName, k -> new ConcurrentLinkedDeque<>()); - phaseHist.addLast(breakdown); - while (phaseHist.size() > MAX_PAUSE_HISTORY) { - phaseHist.removeFirst(); - } - - if (duration > 10) { - LOGGER.info( - String.format( - "GC Pause detected: %s | Action: %s | Cause: %s | Duration: %d ms", - gcName, gcAction, gcCause, duration)); - } + + @Override + public void handleNotification(Notification notification, Object handback) { + if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + + String gcName = info.getGcName(); + String gcAction = info.getGcAction(); + String gcCause = info.getGcCause(); + GcInfo gcInfo = info.getGcInfo(); + long duration = gcInfo.getDuration(); + + // FILTERING LOGIC: + // Azul C4 exposes "GPGC" (Concurrent Cycle) and "GPGC Pauses" (STW Pauses). + // We MUST ignore "GPGC" because it reports cycle time (hundreds of ms) which is NOT a pause. + if ("GPGC".equals(gcName)) { + return; + } + + // Also ignore other known concurrent cycle beans if they appear + if (gcName.contains("Cycles") && !gcName.contains("Pauses")) { + return; + } + + // Pause duration history (existing logic) + ConcurrentLinkedDeque history = pauseHistory.computeIfAbsent(gcName, k -> new ConcurrentLinkedDeque<>()); + history.addLast(duration); + while (history.size() > MAX_PAUSE_HISTORY) { + history.removeFirst(); + } + + // Phase breakdown extraction (new logic) + Map phaseTimes = extractPhaseTimes(gcInfo, gcName, gcAction); + GCPhaseBreakdown breakdown = new GCPhaseBreakdown(duration, phaseTimes, System.currentTimeMillis()); + + ConcurrentLinkedDeque phaseHist = phaseHistory.computeIfAbsent(gcName, k -> new ConcurrentLinkedDeque<>()); + phaseHist.addLast(breakdown); + while (phaseHist.size() > MAX_PAUSE_HISTORY) { + phaseHist.removeFirst(); + } + + if (duration > 10) { + LOGGER.info(String.format("GC Pause detected: %s | Action: %s | Cause: %s | Duration: %d ms", gcName, gcAction, gcCause, duration)); + } + } } - } - - /** - * Extracts GC phase timings from GcInfo metadata. - * - *

    This is JVM and collector-specific - detailed phase data may not be available on all - * platforms. The standard GcInfo API does not expose phase-level timing; vendors may provide this - * via custom MBeans or extended attributes. - * - *

    For production-grade phase analysis, consider parsing GC logs with -Xlog:gc*=debug or using - * vendor-specific monitoring tools. - * - * @param gcInfo GC information from notification - * @param gcName Name of garbage collector (e.g., "G1 Young Generation", "GPGC Pauses") - * @param gcAction GC action string (e.g., "end of minor GC", "end of major GC") - * @return Map of phase names to durations in milliseconds. Contains at minimum a "Total" entry - * with the full pause duration. - */ - private Map extractPhaseTimes(GcInfo gcInfo, String gcName, String gcAction) { - Map phases = new HashMap<>(); - - try { - // Fallback: Always include total duration as baseline - phases.put("Total", gcInfo.getDuration()); - - // Vendor-specific extraction would go here - // GcInfo doesn't expose phases in the standard API - // - // For G1GC: Would need to parse GC logs or use JFR events - // For C4: Would need Azul-specific MBeans - // For ZGC/Shenandoah: Would need to parse logs or use vendor tools - // - // Current implementation provides "Total" phase as a foundation. - // Future enhancement: Add vendor-specific extraction logic. - - } catch (Exception e) { - LOGGER.fine("Could not extract GC phase breakdown: " + e.getMessage()); - phases.clear(); - phases.put("Total", gcInfo.getDuration()); + + /** + * Extracts GC phase timings from GcInfo metadata. + * + *

    + * This is JVM and collector-specific - detailed phase data may not be available on all platforms. The standard GcInfo API does not expose phase-level + * timing; vendors may provide this via custom MBeans or extended attributes. + * + *

    + * For production-grade phase analysis, consider parsing GC logs with -Xlog:gc*=debug or using vendor-specific monitoring tools. + * + * @param gcInfo + * GC information from notification + * @param gcName + * Name of garbage collector (e.g., "G1 Young Generation", "GPGC Pauses") + * @param gcAction + * GC action string (e.g., "end of minor GC", "end of major GC") + * @return Map of phase names to durations in milliseconds. Contains at minimum a "Total" entry with the full pause duration. + */ + private Map extractPhaseTimes(GcInfo gcInfo, String gcName, String gcAction) { + Map phases = new HashMap<>(); + + try { + // Fallback: Always include total duration as baseline + phases.put("Total", gcInfo.getDuration()); + + // Vendor-specific extraction would go here + // GcInfo doesn't expose phases in the standard API + // + // For G1GC: Would need to parse GC logs or use JFR events + // For C4: Would need Azul-specific MBeans + // For ZGC/Shenandoah: Would need to parse logs or use vendor tools + // + // Current implementation provides "Total" phase as a foundation. + // Future enhancement: Add vendor-specific extraction logic. + + } catch (Exception e) { + LOGGER.fine("Could not extract GC phase breakdown: " + e.getMessage()); + phases.clear(); + phases.put("Total", gcInfo.getDuration()); + } + + return phases; } - return phases; - } + public List collectGCStats() { + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); + MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); - public List collectGCStats() { - List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); - MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); - MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); + List statsList = new ArrayList<>(); - List statsList = new ArrayList<>(); + for (GarbageCollectorMXBean gcBean : gcBeans) { + String gcName = gcBean.getName(); - for (GarbageCollectorMXBean gcBean : gcBeans) { - String gcName = gcBean.getName(); + // Exclude concurrent cycle collectors from the public stats to avoid confusion + if ("GPGC".equals(gcName) || (gcName.contains("Cycles") && !gcName.contains("Pauses"))) { + continue; + } - // Exclude concurrent cycle collectors from the public stats to avoid confusion - if ("GPGC".equals(gcName) || (gcName.contains("Cycles") && !gcName.contains("Pauses"))) { - continue; - } + GCStats stats = new GCStats(); + stats.setGcName(gcName); + stats.setCollectionCount(gcBean.getCollectionCount()); + stats.setCollectionTime(gcBean.getCollectionTime()); - GCStats stats = new GCStats(); - stats.setGcName(gcName); - stats.setCollectionCount(gcBean.getCollectionCount()); - stats.setCollectionTime(gcBean.getCollectionTime()); + ConcurrentLinkedDeque history = pauseHistory.get(gcName); + if (history != null && !history.isEmpty()) { + List pauses = new ArrayList<>(history); + stats.setLastPauseDuration(pauses.get(pauses.size() - 1)); - ConcurrentLinkedDeque history = pauseHistory.get(gcName); - if (history != null && !history.isEmpty()) { - List pauses = new ArrayList<>(history); - stats.setLastPauseDuration(pauses.get(pauses.size() - 1)); + stats.setRecentPauses(pauses.subList(Math.max(0, pauses.size() - 100), pauses.size())); - stats.setRecentPauses(pauses.subList(Math.max(0, pauses.size() - 100), pauses.size())); + List sortedPauses = pauses.stream().sorted().collect(Collectors.toList()); - List sortedPauses = pauses.stream().sorted().collect(Collectors.toList()); + stats.setPercentiles(calculatePercentiles(sortedPauses)); + } else { + stats.setLastPauseDuration(0); + stats.setRecentPauses(Collections.emptyList()); + stats.setPercentiles(new GCStats.PausePercentiles(0, 0, 0, 0, 0)); + } - stats.setPercentiles(calculatePercentiles(sortedPauses)); - } else { - stats.setLastPauseDuration(0); - stats.setRecentPauses(Collections.emptyList()); - stats.setPercentiles(new GCStats.PausePercentiles(0, 0, 0, 0, 0)); - } + stats.setTotalMemory(heapUsage.getMax()); + stats.setUsedMemory(heapUsage.getUsed()); + stats.setFreeMemory(heapUsage.getMax() - heapUsage.getUsed()); - stats.setTotalMemory(heapUsage.getMax()); - stats.setUsedMemory(heapUsage.getUsed()); - stats.setFreeMemory(heapUsage.getMax() - heapUsage.getUsed()); + // Add phase breakdown if available + ConcurrentLinkedDeque phaseHist = phaseHistory.get(gcName); + if (phaseHist != null && !phaseHist.isEmpty()) { + stats.setPhaseBreakdown(calculatePhaseStats(new ArrayList<>(phaseHist))); + } - // Add phase breakdown if available - ConcurrentLinkedDeque phaseHist = phaseHistory.get(gcName); - if (phaseHist != null && !phaseHist.isEmpty()) { - stats.setPhaseBreakdown(calculatePhaseStats(new ArrayList<>(phaseHist))); - } + statsList.add(stats); + } - statsList.add(stats); + return statsList; } - return statsList; - } + private GCStats.PausePercentiles calculatePercentiles(List sortedPauses) { + if (sortedPauses.isEmpty()) { + return new GCStats.PausePercentiles(0, 0, 0, 0, 0); + } - private GCStats.PausePercentiles calculatePercentiles(List sortedPauses) { - if (sortedPauses.isEmpty()) { - return new GCStats.PausePercentiles(0, 0, 0, 0, 0); + int size = sortedPauses.size(); + return new GCStats.PausePercentiles(percentile(sortedPauses, 0.50), percentile(sortedPauses, 0.95), percentile(sortedPauses, 0.99), + percentile(sortedPauses, 0.999), sortedPauses.get(size - 1)); } - int size = sortedPauses.size(); - return new GCStats.PausePercentiles( - percentile(sortedPauses, 0.50), - percentile(sortedPauses, 0.95), - percentile(sortedPauses, 0.99), - percentile(sortedPauses, 0.999), - sortedPauses.get(size - 1)); - } - - private long percentile(List sortedValues, double percentile) { - int index = (int) Math.ceil(percentile * sortedValues.size()) - 1; - index = Math.max(0, Math.min(index, sortedValues.size() - 1)); - return sortedValues.get(index); - } - - /** - * Calculates per-phase statistics from breakdown history. - * - *

    Groups phase durations by phase name and computes percentiles for each phase independently. - * This allows identifying which phases contribute most to pause times (e.g., "Mark" vs "Evacuate" - * in G1GC). - * - * @param breakdowns List of GC phase breakdowns from notification history - * @return Map of phase names to statistics (count, percentiles) - */ - private Map calculatePhaseStats(List breakdowns) { - Map phaseStatsMap = new HashMap<>(); - - if (breakdowns.isEmpty()) { - return phaseStatsMap; + private long percentile(List sortedValues, double percentile) { + int index = (int) Math.ceil(percentile * sortedValues.size()) - 1; + index = Math.max(0, Math.min(index, sortedValues.size() - 1)); + return sortedValues.get(index); } - // Group durations by phase name - Map> phaseGroups = new HashMap<>(); - for (GCPhaseBreakdown breakdown : breakdowns) { - for (Map.Entry entry : breakdown.phaseDurationsMs.entrySet()) { - phaseGroups.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).add(entry.getValue()); - } + /** + * Calculates per-phase statistics from breakdown history. + * + *

    + * Groups phase durations by phase name and computes percentiles for each phase independently. This allows identifying which phases contribute most to pause + * times (e.g., "Mark" vs "Evacuate" in G1GC). + * + * @param breakdowns + * List of GC phase breakdowns from notification history + * @return Map of phase names to statistics (count, percentiles) + */ + private Map calculatePhaseStats(List breakdowns) { + Map phaseStatsMap = new HashMap<>(); + + if (breakdowns.isEmpty()) { + return phaseStatsMap; + } + + // Group durations by phase name + Map> phaseGroups = new HashMap<>(); + for (GCPhaseBreakdown breakdown : breakdowns) { + for (Map.Entry entry : breakdown.phaseDurationsMs.entrySet()) { + phaseGroups.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).add(entry.getValue()); + } + } + + // Calculate percentiles for each phase + for (Map.Entry> entry : phaseGroups.entrySet()) { + String phaseName = entry.getKey(); + List durations = entry.getValue(); + Collections.sort(durations); + + PhaseStats stats = new PhaseStats(phaseName, durations.size(), percentile(durations, 0.50), percentile(durations, 0.95), + percentile(durations, 0.99), durations.get(durations.size() - 1) // max + ); + + phaseStatsMap.put(phaseName, stats); + } + + return phaseStatsMap; } - // Calculate percentiles for each phase - for (Map.Entry> entry : phaseGroups.entrySet()) { - String phaseName = entry.getKey(); - List durations = entry.getValue(); - Collections.sort(durations); - - PhaseStats stats = - new PhaseStats( - phaseName, - durations.size(), - percentile(durations, 0.50), - percentile(durations, 0.95), - percentile(durations, 0.99), - durations.get(durations.size() - 1) // max - ); - - phaseStatsMap.put(phaseName, stats); + public void resetStats() { + pauseHistory.clear(); + phaseHistory.clear(); + LOGGER.info("GC statistics reset"); } - - return phaseStatsMap; - } - - public void resetStats() { - pauseHistory.clear(); - phaseHistory.clear(); - LOGGER.info("GC statistics reset"); - } } diff --git a/src/main/java/fish/payara/trader/monitoring/GCPauseMonitor.java b/src/main/java/fish/payara/trader/monitoring/GCPauseMonitor.java index c45adcb..7065b73 100644 --- a/src/main/java/fish/payara/trader/monitoring/GCPauseMonitor.java +++ b/src/main/java/fish/payara/trader/monitoring/GCPauseMonitor.java @@ -22,208 +22,183 @@ @ApplicationScoped public class GCPauseMonitor implements NotificationListener { - private static final Logger LOGGER = Logger.getLogger(GCPauseMonitor.class.getName()); + private static final Logger LOGGER = Logger.getLogger(GCPauseMonitor.class.getName()); - private static final int MAX_PAUSE_HISTORY = 500; + private static final int MAX_PAUSE_HISTORY = 500; - private final ConcurrentLinkedDeque pauseHistory = new ConcurrentLinkedDeque<>(); + private final ConcurrentLinkedDeque pauseHistory = new ConcurrentLinkedDeque<>(); - private final AtomicLong totalPauseCount = new AtomicLong(0); - private final AtomicLong totalPauseTimeMs = new AtomicLong(0); - private volatile long maxPauseMs = 0; + private final AtomicLong totalPauseCount = new AtomicLong(0); + private final AtomicLong totalPauseTimeMs = new AtomicLong(0); + private volatile long maxPauseMs = 0; - private final AtomicLong violationsOver10ms = new AtomicLong(0); - private final AtomicLong violationsOver50ms = new AtomicLong(0); - private final AtomicLong violationsOver100ms = new AtomicLong(0); + private final AtomicLong violationsOver10ms = new AtomicLong(0); + private final AtomicLong violationsOver50ms = new AtomicLong(0); + private final AtomicLong violationsOver100ms = new AtomicLong(0); - private final List emitters = new ArrayList<>(); + private final List emitters = new ArrayList<>(); - @PostConstruct - public void init() { - LOGGER.info("Initializing GC Pause Monitor with JMX notifications"); + @PostConstruct + public void init() { + LOGGER.info("Initializing GC Pause Monitor with JMX notifications"); - List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); - for (GarbageCollectorMXBean gcBean : gcBeans) { - if (gcBean instanceof NotificationEmitter) { - NotificationEmitter emitter = (NotificationEmitter) gcBean; - emitter.addNotificationListener(this, null, null); - emitters.add(emitter); - LOGGER.info("Registered GC notification listener for: " + gcBean.getName()); - } - } + for (GarbageCollectorMXBean gcBean : gcBeans) { + if (gcBean instanceof NotificationEmitter) { + NotificationEmitter emitter = (NotificationEmitter) gcBean; + emitter.addNotificationListener(this, null, null); + emitters.add(emitter); + LOGGER.info("Registered GC notification listener for: " + gcBean.getName()); + } + } - if (emitters.isEmpty()) { - LOGGER.warning("No GC notification emitters found - pause monitoring may be limited"); - } - } - - @PreDestroy - public void cleanup() { - for (NotificationEmitter emitter : emitters) { - try { - emitter.removeNotificationListener(this); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to remove GC notification listener", e); - } + if (emitters.isEmpty()) { + LOGGER.warning("No GC notification emitters found - pause monitoring may be limited"); + } } - emitters.clear(); - } - - @Override - public void handleNotification(Notification notification, Object handback) { - if (!notification - .getType() - .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { - return; + + @PreDestroy + public void cleanup() { + for (NotificationEmitter emitter : emitters) { + try { + emitter.removeNotificationListener(this); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to remove GC notification listener", e); + } + } + emitters.clear(); } - try { - CompositeData cd = (CompositeData) notification.getUserData(); - GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd); - String gcName = info.getGcName(); + @Override + public void handleNotification(Notification notification, Object handback) { + if (!notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + return; + } - if ("GPGC".equals(gcName) || (gcName.contains("Cycles") && !gcName.contains("Pauses"))) { - return; - } + try { + CompositeData cd = (CompositeData) notification.getUserData(); + GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd); + String gcName = info.getGcName(); - GcInfo gcInfo = info.getGcInfo(); - long pauseMs = gcInfo.getDuration(); + if ("GPGC".equals(gcName) || (gcName.contains("Cycles") && !gcName.contains("Pauses"))) { + return; + } - recordPause(pauseMs, gcName, info.getGcAction()); + GcInfo gcInfo = info.getGcInfo(); + long pauseMs = gcInfo.getDuration(); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Error processing GC notification", e); - } - } + recordPause(pauseMs, gcName, info.getGcAction()); - private void recordPause(long pauseMs, String gcName, String gcAction) { - pauseHistory.addLast(pauseMs); - if (pauseHistory.size() > MAX_PAUSE_HISTORY) { - pauseHistory.removeFirst(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error processing GC notification", e); + } } - totalPauseCount.incrementAndGet(); - totalPauseTimeMs.addAndGet(pauseMs); + private void recordPause(long pauseMs, String gcName, String gcAction) { + pauseHistory.addLast(pauseMs); + if (pauseHistory.size() > MAX_PAUSE_HISTORY) { + pauseHistory.removeFirst(); + } + + totalPauseCount.incrementAndGet(); + totalPauseTimeMs.addAndGet(pauseMs); - if (pauseMs > maxPauseMs) { - synchronized (this) { if (pauseMs > maxPauseMs) { - maxPauseMs = pauseMs; + synchronized (this) { + if (pauseMs > maxPauseMs) { + maxPauseMs = pauseMs; + } + } } - } - } - if (pauseMs > 100) { - violationsOver100ms.incrementAndGet(); - violationsOver50ms.incrementAndGet(); - violationsOver10ms.incrementAndGet(); - } else if (pauseMs > 50) { - violationsOver50ms.incrementAndGet(); - violationsOver10ms.incrementAndGet(); - } else if (pauseMs > 10) { - violationsOver10ms.incrementAndGet(); + if (pauseMs > 100) { + violationsOver100ms.incrementAndGet(); + violationsOver50ms.incrementAndGet(); + violationsOver10ms.incrementAndGet(); + } else if (pauseMs > 50) { + violationsOver50ms.incrementAndGet(); + violationsOver10ms.incrementAndGet(); + } else if (pauseMs > 10) { + violationsOver10ms.incrementAndGet(); + } + + if (pauseMs > 100) { + LOGGER.warning(String.format("Large GC pause detected: %d ms [%s - %s]", pauseMs, gcName, gcAction)); + } else if (pauseMs > 50) { + LOGGER.info(String.format("Notable GC pause: %d ms [%s - %s]", pauseMs, gcName, gcAction)); + } } - if (pauseMs > 100) { - LOGGER.warning( - String.format("Large GC pause detected: %d ms [%s - %s]", pauseMs, gcName, gcAction)); - } else if (pauseMs > 50) { - LOGGER.info(String.format("Notable GC pause: %d ms [%s - %s]", pauseMs, gcName, gcAction)); + public GCPauseStats getStats() { + List pauses = new ArrayList<>(pauseHistory); + + if (pauses.isEmpty()) { + return new GCPauseStats(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + + Collections.sort(pauses); + + long p50 = percentile(pauses, 0.50); + long p95 = percentile(pauses, 0.95); + long p99 = percentile(pauses, 0.99); + long p999 = percentile(pauses, 0.999); + long max = pauses.get(pauses.size() - 1); + + long count = totalPauseCount.get(); + long totalTime = totalPauseTimeMs.get(); + double avgPause = count > 0 ? (double) totalTime / count : 0; + + return new GCPauseStats(count, totalTime, avgPause, p50, p95, p99, p999, maxPauseMs, // All-time max + violationsOver10ms.get(), violationsOver50ms.get(), violationsOver100ms.get(), pauses.size() // Sample size for percentiles + ); } - } - public GCPauseStats getStats() { - List pauses = new ArrayList<>(pauseHistory); + private long percentile(List sortedValues, double percentile) { + int index = (int) Math.ceil(percentile * sortedValues.size()) - 1; + index = Math.max(0, Math.min(index, sortedValues.size() - 1)); + return sortedValues.get(index); + } - if (pauses.isEmpty()) { - return new GCPauseStats(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + public void reset() { + pauseHistory.clear(); + totalPauseCount.set(0); + totalPauseTimeMs.set(0); + maxPauseMs = 0; + violationsOver10ms.set(0); + violationsOver50ms.set(0); + violationsOver100ms.set(0); + LOGGER.info("GC pause statistics reset"); } - Collections.sort(pauses); - - long p50 = percentile(pauses, 0.50); - long p95 = percentile(pauses, 0.95); - long p99 = percentile(pauses, 0.99); - long p999 = percentile(pauses, 0.999); - long max = pauses.get(pauses.size() - 1); - - long count = totalPauseCount.get(); - long totalTime = totalPauseTimeMs.get(); - double avgPause = count > 0 ? (double) totalTime / count : 0; - - return new GCPauseStats( - count, - totalTime, - avgPause, - p50, - p95, - p99, - p999, - maxPauseMs, // All-time max - violationsOver10ms.get(), - violationsOver50ms.get(), - violationsOver100ms.get(), - pauses.size() // Sample size for percentiles - ); - } - - private long percentile(List sortedValues, double percentile) { - int index = (int) Math.ceil(percentile * sortedValues.size()) - 1; - index = Math.max(0, Math.min(index, sortedValues.size() - 1)); - return sortedValues.get(index); - } - - public void reset() { - pauseHistory.clear(); - totalPauseCount.set(0); - totalPauseTimeMs.set(0); - maxPauseMs = 0; - violationsOver10ms.set(0); - violationsOver50ms.set(0); - violationsOver100ms.set(0); - LOGGER.info("GC pause statistics reset"); - } - - public static class GCPauseStats { - public final long totalPauseCount; - public final long totalPauseTimeMs; - public final double avgPauseMs; - public final long p50Ms; - public final long p95Ms; - public final long p99Ms; - public final long p999Ms; - public final long maxMs; - public final long violationsOver10ms; - public final long violationsOver50ms; - public final long violationsOver100ms; - public final int sampleSize; - - public GCPauseStats( - long totalPauseCount, - long totalPauseTimeMs, - double avgPauseMs, - long p50Ms, - long p95Ms, - long p99Ms, - long p999Ms, - long maxMs, - long violationsOver10ms, - long violationsOver50ms, - long violationsOver100ms, - int sampleSize) { - this.totalPauseCount = totalPauseCount; - this.totalPauseTimeMs = totalPauseTimeMs; - this.avgPauseMs = avgPauseMs; - this.p50Ms = p50Ms; - this.p95Ms = p95Ms; - this.p99Ms = p99Ms; - this.p999Ms = p999Ms; - this.maxMs = maxMs; - this.violationsOver10ms = violationsOver10ms; - this.violationsOver50ms = violationsOver50ms; - this.violationsOver100ms = violationsOver100ms; - this.sampleSize = sampleSize; + public static class GCPauseStats { + public final long totalPauseCount; + public final long totalPauseTimeMs; + public final double avgPauseMs; + public final long p50Ms; + public final long p95Ms; + public final long p99Ms; + public final long p999Ms; + public final long maxMs; + public final long violationsOver10ms; + public final long violationsOver50ms; + public final long violationsOver100ms; + public final int sampleSize; + + public GCPauseStats(long totalPauseCount, long totalPauseTimeMs, double avgPauseMs, long p50Ms, long p95Ms, long p99Ms, long p999Ms, long maxMs, + long violationsOver10ms, long violationsOver50ms, long violationsOver100ms, int sampleSize) { + this.totalPauseCount = totalPauseCount; + this.totalPauseTimeMs = totalPauseTimeMs; + this.avgPauseMs = avgPauseMs; + this.p50Ms = p50Ms; + this.p95Ms = p95Ms; + this.p99Ms = p99Ms; + this.p999Ms = p999Ms; + this.maxMs = maxMs; + this.violationsOver10ms = violationsOver10ms; + this.violationsOver50ms = violationsOver50ms; + this.violationsOver100ms = violationsOver100ms; + this.sampleSize = sampleSize; + } } - } } diff --git a/src/main/java/fish/payara/trader/monitoring/SLAMonitorService.java b/src/main/java/fish/payara/trader/monitoring/SLAMonitorService.java index 09518d2..e7767cc 100644 --- a/src/main/java/fish/payara/trader/monitoring/SLAMonitorService.java +++ b/src/main/java/fish/payara/trader/monitoring/SLAMonitorService.java @@ -8,87 +8,77 @@ @ApplicationScoped public class SLAMonitorService { - private static final Logger LOGGER = Logger.getLogger(SLAMonitorService.class.getName()); + private static final Logger LOGGER = Logger.getLogger(SLAMonitorService.class.getName()); - private static final long SLA_10MS = 10; - private static final long SLA_50MS = 50; - private static final long SLA_100MS = 100; + private static final long SLA_10MS = 10; + private static final long SLA_50MS = 50; + private static final long SLA_100MS = 100; - private final AtomicLong violationsOver10ms = new AtomicLong(0); - private final AtomicLong violationsOver50ms = new AtomicLong(0); - private final AtomicLong violationsOver100ms = new AtomicLong(0); - private final AtomicLong totalOperations = new AtomicLong(0); + private final AtomicLong violationsOver10ms = new AtomicLong(0); + private final AtomicLong violationsOver50ms = new AtomicLong(0); + private final AtomicLong violationsOver100ms = new AtomicLong(0); + private final AtomicLong totalOperations = new AtomicLong(0); - private final ConcurrentHashMap violationsByMinute = new ConcurrentHashMap<>(); + private final ConcurrentHashMap violationsByMinute = new ConcurrentHashMap<>(); - public void recordOperation(long latencyMs) { - totalOperations.incrementAndGet(); + public void recordOperation(long latencyMs) { + totalOperations.incrementAndGet(); - if (latencyMs > SLA_100MS) { - violationsOver100ms.incrementAndGet(); - violationsOver50ms.incrementAndGet(); - violationsOver10ms.incrementAndGet(); - recordViolation(); - } else if (latencyMs > SLA_50MS) { - violationsOver50ms.incrementAndGet(); - violationsOver10ms.incrementAndGet(); - recordViolation(); - } else if (latencyMs > SLA_10MS) { - violationsOver10ms.incrementAndGet(); - recordViolation(); + if (latencyMs > SLA_100MS) { + violationsOver100ms.incrementAndGet(); + violationsOver50ms.incrementAndGet(); + violationsOver10ms.incrementAndGet(); + recordViolation(); + } else if (latencyMs > SLA_50MS) { + violationsOver50ms.incrementAndGet(); + violationsOver10ms.incrementAndGet(); + recordViolation(); + } else if (latencyMs > SLA_10MS) { + violationsOver10ms.incrementAndGet(); + recordViolation(); + } } - } - private void recordViolation() { - long currentMinute = System.currentTimeMillis() / 60000; - violationsByMinute.merge(currentMinute, 1L, Long::sum); + private void recordViolation() { + long currentMinute = System.currentTimeMillis() / 60000; + violationsByMinute.merge(currentMinute, 1L, Long::sum); - long fiveMinutesAgo = currentMinute - 5; - violationsByMinute.keySet().removeIf(minute -> minute < fiveMinutesAgo); - } + long fiveMinutesAgo = currentMinute - 5; + violationsByMinute.keySet().removeIf(minute -> minute < fiveMinutesAgo); + } - public SLAStats getStats() { - long total = totalOperations.get(); + public SLAStats getStats() { + long total = totalOperations.get(); - return new SLAStats( - total, - violationsOver10ms.get(), - violationsOver50ms.get(), - violationsOver100ms.get(), - total > 0 ? (double) violationsOver10ms.get() / total * 100 : 0, - violationsByMinute.values().stream().mapToLong(Long::longValue).sum()); - } + return new SLAStats(total, violationsOver10ms.get(), violationsOver50ms.get(), violationsOver100ms.get(), + total > 0 ? (double) violationsOver10ms.get() / total * 100 : 0, violationsByMinute.values().stream().mapToLong(Long::longValue).sum()); + } - public void reset() { - violationsOver10ms.set(0); - violationsOver50ms.set(0); - violationsOver100ms.set(0); - totalOperations.set(0); - violationsByMinute.clear(); - LOGGER.info("SLA statistics reset"); - } + public void reset() { + violationsOver10ms.set(0); + violationsOver50ms.set(0); + violationsOver100ms.set(0); + totalOperations.set(0); + violationsByMinute.clear(); + LOGGER.info("SLA statistics reset"); + } - public static class SLAStats { - public final long totalOperations; - public final long violationsOver10ms; - public final long violationsOver50ms; - public final long violationsOver100ms; - public final double violationRate; - public final long recentViolations; // Last 5 minutes + public static class SLAStats { + public final long totalOperations; + public final long violationsOver10ms; + public final long violationsOver50ms; + public final long violationsOver100ms; + public final double violationRate; + public final long recentViolations; // Last 5 minutes - public SLAStats( - long totalOperations, - long violationsOver10ms, - long violationsOver50ms, - long violationsOver100ms, - double violationRate, - long recentViolations) { - this.totalOperations = totalOperations; - this.violationsOver10ms = violationsOver10ms; - this.violationsOver50ms = violationsOver50ms; - this.violationsOver100ms = violationsOver100ms; - this.violationRate = violationRate; - this.recentViolations = recentViolations; + public SLAStats(long totalOperations, long violationsOver10ms, long violationsOver50ms, long violationsOver100ms, double violationRate, + long recentViolations) { + this.totalOperations = totalOperations; + this.violationsOver10ms = violationsOver10ms; + this.violationsOver50ms = violationsOver50ms; + this.violationsOver100ms = violationsOver100ms; + this.violationRate = violationRate; + this.recentViolations = recentViolations; + } } - } } diff --git a/src/main/java/fish/payara/trader/pressure/AllocationMode.java b/src/main/java/fish/payara/trader/pressure/AllocationMode.java index a9eb0e0..62f4a7c 100644 --- a/src/main/java/fish/payara/trader/pressure/AllocationMode.java +++ b/src/main/java/fish/payara/trader/pressure/AllocationMode.java @@ -1,79 +1,64 @@ package fish.payara.trader.pressure; public enum AllocationMode { - OFF(0, 0, 0, ScenarioType.NONE, "No allocation"), + OFF(0, 0, 0, ScenarioType.NONE, "No allocation"), - STEADY_LOAD( - 200, // MB/sec allocation rate - 512, // MB live set size - 0, // No growth - ScenarioType.STEADY, - "Steady 200 MB/sec allocation, 512 MB live set - Tests baseline GC behavior"), + STEADY_LOAD(200, // MB/sec allocation rate + 512, // MB live set size + 0, // No growth + ScenarioType.STEADY, "Steady 200 MB/sec allocation, 512 MB live set - Tests baseline GC behavior"), - GROWING_HEAP( - 150, // MB/sec allocation rate - 2048, // MB target live set - 60, // seconds to reach target - ScenarioType.GROWING, - "Growing live set 100 MB -> 2 GB over 60s - Tests mixed collection scaling"), + GROWING_HEAP(150, // MB/sec allocation rate + 2048, // MB target live set + 60, // seconds to reach target + ScenarioType.GROWING, "Growing live set 100 MB -> 2 GB over 60s - Tests mixed collection scaling"), - PROMOTION_STORM( - 300, // MB/sec allocation rate - 1024, // MB live set - 0, // No growth - ScenarioType.PROMOTION, - "High promotion rate (50% survival) - Tests old gen collection efficiency"), + PROMOTION_STORM(300, // MB/sec allocation rate + 1024, // MB live set + 0, // No growth + ScenarioType.PROMOTION, "High promotion rate (50% survival) - Tests old gen collection efficiency"), - FRAGMENTATION( - 200, // MB/sec allocation rate - 1024, // MB live set - 0, // No growth - ScenarioType.FRAGMENTATION, - "Small objects, random lifetimes - Tests compaction behavior"), + FRAGMENTATION(200, // MB/sec allocation rate + 1024, // MB live set + 0, // No growth + ScenarioType.FRAGMENTATION, "Small objects, random lifetimes - Tests compaction behavior"), - CROSS_GEN_REFS( - 150, // MB/sec allocation rate - 800, // MB live set in old gen - 0, // No growth - ScenarioType.CROSS_REF, - "Many old->young references - Tests remembered set overhead"); + CROSS_GEN_REFS(150, // MB/sec allocation rate + 800, // MB live set in old gen + 0, // No growth + ScenarioType.CROSS_REF, "Many old->young references - Tests remembered set overhead"); - private final int allocationRateMBPerSec; - private final int liveSetSizeMB; - private final int growthDurationSeconds; - private final ScenarioType scenarioType; - private final String description; + private final int allocationRateMBPerSec; + private final int liveSetSizeMB; + private final int growthDurationSeconds; + private final ScenarioType scenarioType; + private final String description; - AllocationMode( - int allocationRateMBPerSec, - int liveSetSizeMB, - int growthDurationSeconds, - ScenarioType scenarioType, - String description) { - this.allocationRateMBPerSec = allocationRateMBPerSec; - this.liveSetSizeMB = liveSetSizeMB; - this.growthDurationSeconds = growthDurationSeconds; - this.scenarioType = scenarioType; - this.description = description; - } + AllocationMode(int allocationRateMBPerSec, int liveSetSizeMB, int growthDurationSeconds, ScenarioType scenarioType, String description) { + this.allocationRateMBPerSec = allocationRateMBPerSec; + this.liveSetSizeMB = liveSetSizeMB; + this.growthDurationSeconds = growthDurationSeconds; + this.scenarioType = scenarioType; + this.description = description; + } - public int getAllocationRateMBPerSec() { - return allocationRateMBPerSec; - } + public int getAllocationRateMBPerSec() { + return allocationRateMBPerSec; + } - public int getLiveSetSizeMB() { - return liveSetSizeMB; - } + public int getLiveSetSizeMB() { + return liveSetSizeMB; + } - public int getGrowthDurationSeconds() { - return growthDurationSeconds; - } + public int getGrowthDurationSeconds() { + return growthDurationSeconds; + } - public ScenarioType getScenarioType() { - return scenarioType; - } + public ScenarioType getScenarioType() { + return scenarioType; + } - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } } diff --git a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java index dad90e6..5b27c10 100644 --- a/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java +++ b/src/main/java/fish/payara/trader/pressure/MemoryPressureService.java @@ -16,431 +16,413 @@ import java.util.logging.Logger; /** - * Service to generate controlled memory pressure for GC stress testing. Updated to use - * scenario-based testing targeting G1 vs C4 differences. + * Service to generate controlled memory pressure for GC stress testing. Updated to use scenario-based testing targeting G1 vs C4 differences. */ @ApplicationScoped public class MemoryPressureService { - private static final Logger LOGGER = Logger.getLogger(MemoryPressureService.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MemoryPressureService.class.getName()); - private volatile AllocationMode currentMode = AllocationMode.OFF; - private volatile boolean running = false; - private Future pressureTask; + private volatile AllocationMode currentMode = AllocationMode.OFF; + private volatile boolean running = false; + private Future pressureTask; - private final AtomicLong totalBytesAllocated = new AtomicLong(0); - private long lastStatsTime = System.currentTimeMillis(); + private final AtomicLong totalBytesAllocated = new AtomicLong(0); + private long lastStatsTime = System.currentTimeMillis(); - // Live set management - private final Deque liveSet = new LinkedList<>(); - private final AtomicLong liveSetBytesAllocated = new AtomicLong(0); + // Live set management + private final Deque liveSet = new LinkedList<>(); + private final AtomicLong liveSetBytesAllocated = new AtomicLong(0); - // For Promotion Storm (thread-safe as multiple threads add to it) - private final Deque promotableObjects = new ConcurrentLinkedDeque<>(); + // For Promotion Storm (thread-safe as multiple threads add to it) + private final Deque promotableObjects = new ConcurrentLinkedDeque<>(); - // For Cross-Gen Refs scenario - holders in old gen that reference young objects - private final Deque crossRefHolders = new LinkedList<>(); - private final AtomicLong crossRefBytesAllocated = new AtomicLong(0); + // For Cross-Gen Refs scenario - holders in old gen that reference young objects + private final Deque crossRefHolders = new LinkedList<>(); + private final AtomicLong crossRefBytesAllocated = new AtomicLong(0); - // Scenario state - private final AtomicLong scenarioStartTime = new AtomicLong(0); + // Scenario state + private final AtomicLong scenarioStartTime = new AtomicLong(0); - /** - * Holder object that lives in old generation and holds a reference to a young object. Every - * update to youngRef triggers G1's write barrier and remembered set maintenance. - */ - private static class RefHolder { - volatile Object youngRef; // Reference to young gen object - updated frequently - final byte[] padding; // Padding to make holder substantial (~1MB each) + /** + * Holder object that lives in old generation and holds a reference to a young object. Every update to youngRef triggers G1's write barrier and remembered + * set maintenance. + */ + private static class RefHolder { + volatile Object youngRef; // Reference to young gen object - updated frequently + final byte[] padding; // Padding to make holder substantial (~1MB each) - RefHolder(int paddingSize) { - this.padding = new byte[paddingSize]; - ThreadLocalRandom.current().nextBytes(this.padding); + RefHolder(int paddingSize) { + this.padding = new byte[paddingSize]; + ThreadLocalRandom.current().nextBytes(this.padding); + } } - } - @Inject @VirtualThreadExecutor private ManagedExecutorService executorService; + @Inject + @VirtualThreadExecutor + private ManagedExecutorService executorService; - @PostConstruct - public void init() { - LOGGER.info("MemoryPressureService initialized"); - } - - public synchronized void setAllocationMode(AllocationMode mode) { - if (mode == currentMode) { - return; + @PostConstruct + public void init() { + LOGGER.info("MemoryPressureService initialized"); } - LOGGER.info("Changing allocation mode from " + currentMode + " to " + mode); - currentMode = mode; - - if (mode == AllocationMode.OFF) { - stopPressure(); - } else { - // clear previous state - liveSet.clear(); - liveSetBytesAllocated.set(0); - promotableObjects.clear(); - crossRefHolders.clear(); - crossRefBytesAllocated.set(0); - scenarioStartTime.set(System.currentTimeMillis()); - - startPressure(); + public synchronized void setAllocationMode(AllocationMode mode) { + if (mode == currentMode) { + return; + } + + LOGGER.info("Changing allocation mode from " + currentMode + " to " + mode); + currentMode = mode; + + if (mode == AllocationMode.OFF) { + stopPressure(); + } else { + // clear previous state + liveSet.clear(); + liveSetBytesAllocated.set(0); + promotableObjects.clear(); + crossRefHolders.clear(); + crossRefBytesAllocated.set(0); + scenarioStartTime.set(System.currentTimeMillis()); + + startPressure(); + } } - } - private synchronized void startPressure() { - if (running) { - return; - } + private synchronized void startPressure() { + if (running) { + return; + } - running = true; - totalBytesAllocated.set(0); - lastStatsTime = System.currentTimeMillis(); + running = true; + totalBytesAllocated.set(0); + lastStatsTime = System.currentTimeMillis(); - pressureTask = - executorService.submit( - () -> { - LOGGER.info("Memory pressure generator started with mode: " + currentMode); + pressureTask = executorService.submit(() -> { + LOGGER.info("Memory pressure generator started with mode: " + currentMode); - while (running) { + while (running) { try { - long loopStartTime = System.currentTimeMillis(); - AllocationMode mode = currentMode; - if (mode == AllocationMode.OFF) { - break; - } + long loopStartTime = System.currentTimeMillis(); + AllocationMode mode = currentMode; + if (mode == AllocationMode.OFF) { + break; + } - generateGarbage(mode); + generateGarbage(mode); - long executionTime = System.currentTimeMillis() - loopStartTime; - // Target 10 iterations per second (100ms per iteration) - long sleepTime = 100 - executionTime; + long executionTime = System.currentTimeMillis() - loopStartTime; + // Target 10 iterations per second (100ms per iteration) + long sleepTime = 100 - executionTime; - if (sleepTime > 0) { - Thread.sleep(sleepTime); - } + if (sleepTime > 0) { + Thread.sleep(sleepTime); + } - logStats(); + logStats(); } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; + Thread.currentThread().interrupt(); + break; } catch (Exception e) { - LOGGER.warning("Error in memory pressure generator: " + e.getMessage()); + LOGGER.warning("Error in memory pressure generator: " + e.getMessage()); } - } - - LOGGER.info("Memory pressure generator stopped"); - // Cleanup - liveSet.clear(); - liveSetBytesAllocated.set(0); - promotableObjects.clear(); - crossRefHolders.clear(); - crossRefBytesAllocated.set(0); - }); - } - - private synchronized void stopPressure() { - running = false; - if (pressureTask != null && !pressureTask.isDone()) { - pressureTask.cancel(true); - pressureTask = null; + } + + LOGGER.info("Memory pressure generator stopped"); + // Cleanup + liveSet.clear(); + liveSetBytesAllocated.set(0); + promotableObjects.clear(); + crossRefHolders.clear(); + crossRefBytesAllocated.set(0); + }); } - } - - private void generateGarbage(AllocationMode mode) { - switch (mode.getScenarioType()) { - case STEADY: - executeSteadyLoadScenario(mode); - break; - case GROWING: - executeGrowingHeapScenario(mode); - break; - case PROMOTION: - executePromotionStormScenario(mode); - break; - case FRAGMENTATION: - executeFragmentationScenario(mode); - break; - case CROSS_REF: - executeCrossRefsScenario(mode); - break; - default: - // Do nothing for NONE - break; + + private synchronized void stopPressure() { + running = false; + if (pressureTask != null && !pressureTask.isDone()) { + pressureTask.cancel(true); + pressureTask = null; + } + } + + private void generateGarbage(AllocationMode mode) { + switch (mode.getScenarioType()) { + case STEADY : + executeSteadyLoadScenario(mode); + break; + case GROWING : + executeGrowingHeapScenario(mode); + break; + case PROMOTION : + executePromotionStormScenario(mode); + break; + case FRAGMENTATION : + executeFragmentationScenario(mode); + break; + case CROSS_REF : + executeCrossRefsScenario(mode); + break; + default : + // Do nothing for NONE + break; + } + } + + private void executeSteadyLoadScenario(AllocationMode mode) { + int targetMB = mode.getLiveSetSizeMB(); + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + + // Maintain stable live set (single-threaded) + maintainLiveSet(targetMB); + + // Allocate transient garbage at specified rate across 4 threads + // (100ms iteration = 10 iterations/sec) + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); } - } - - private void executeSteadyLoadScenario(AllocationMode mode) { - int targetMB = mode.getLiveSetSizeMB(); - int rateMBPerSec = mode.getAllocationRateMBPerSec(); - - // Maintain stable live set (single-threaded) - maintainLiveSet(targetMB); - - // Allocate transient garbage at specified rate across 4 threads - // (100ms iteration = 10 iterations/sec) - int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; - - allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); - } - - private void executeGrowingHeapScenario(AllocationMode mode) { - long startTime = scenarioStartTime.get(); - long elapsed = (System.currentTimeMillis() - startTime) / 1000; // seconds - - int startMB = 100; - int targetMB = mode.getLiveSetSizeMB(); - int duration = mode.getGrowthDurationSeconds(); - - // Calculate current target based on linear growth - int currentTargetMB = - elapsed >= duration - ? targetMB - : startMB + (int) ((targetMB - startMB) * elapsed / duration); - - maintainLiveSet(currentTargetMB); - - // Allocate transient garbage - int rateMBPerSec = mode.getAllocationRateMBPerSec(); - int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; - allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); - } - - private void executePromotionStormScenario(AllocationMode mode) { - int rateMBPerSec = mode.getAllocationRateMBPerSec(); - int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; - - // 50% of allocations should survive to old generation - // Allocate half as transient, half as medium-lived - int transientBytes = bytesPerIteration / 2; - int promotableBytes = bytesPerIteration / 2; - - // Multi-threaded allocation for both transient and promotable - allocateTransientGarbageMultiThreaded(transientBytes, 4); - allocatePromotableGarbageMultiThreaded(promotableBytes, 4); - - // Move from thread-safe queue to local live set management - byte[] promoted; - while ((promoted = promotableObjects.poll()) != null) { - liveSet.add(promoted); - liveSetBytesAllocated.addAndGet(promoted.length); + + private void executeGrowingHeapScenario(AllocationMode mode) { + long startTime = scenarioStartTime.get(); + long elapsed = (System.currentTimeMillis() - startTime) / 1000; // seconds + + int startMB = 100; + int targetMB = mode.getLiveSetSizeMB(); + int duration = mode.getGrowthDurationSeconds(); + + // Calculate current target based on linear growth + int currentTargetMB = elapsed >= duration ? targetMB : startMB + (int) ((targetMB - startMB) * elapsed / duration); + + maintainLiveSet(currentTargetMB); + + // Allocate transient garbage + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + allocateTransientGarbageMultiThreaded(bytesPerIteration, 4); } - // Now trim live set if needed (remove oldest) - long targetBytes = mode.getLiveSetSizeMB() * 1024L * 1024L; - while (liveSetBytesAllocated.get() > targetBytes && !liveSet.isEmpty()) { - byte[] removed = liveSet.removeFirst(); - liveSetBytesAllocated.addAndGet(-removed.length); + private void executePromotionStormScenario(AllocationMode mode) { + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + // 50% of allocations should survive to old generation + // Allocate half as transient, half as medium-lived + int transientBytes = bytesPerIteration / 2; + int promotableBytes = bytesPerIteration / 2; + + // Multi-threaded allocation for both transient and promotable + allocateTransientGarbageMultiThreaded(transientBytes, 4); + allocatePromotableGarbageMultiThreaded(promotableBytes, 4); + + // Move from thread-safe queue to local live set management + byte[] promoted; + while ((promoted = promotableObjects.poll()) != null) { + liveSet.add(promoted); + liveSetBytesAllocated.addAndGet(promoted.length); + } + + // Now trim live set if needed (remove oldest) + long targetBytes = mode.getLiveSetSizeMB() * 1024L * 1024L; + while (liveSetBytesAllocated.get() > targetBytes && !liveSet.isEmpty()) { + byte[] removed = liveSet.removeFirst(); + liveSetBytesAllocated.addAndGet(-removed.length); + } } - } - - private void executeFragmentationScenario(AllocationMode mode) { - int targetMB = mode.getLiveSetSizeMB(); - maintainLiveSet(targetMB); - - int rateMBPerSec = mode.getAllocationRateMBPerSec(); - int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; - - allocateFragmentationGarbageMultiThreaded(bytesPerIteration, 4); - } - - private void executeCrossRefsScenario(AllocationMode mode) { - // Maintain old gen holders (these will be promoted after surviving GCs) - maintainCrossRefHolders(mode.getLiveSetSizeMB()); - - int rateMBPerSec = mode.getAllocationRateMBPerSec(); - int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; - - // Create young objects and link them from old gen holders - // This triggers G1's write barriers and remembered set updates - createCrossGenerationalRefsMultiThreaded(bytesPerIteration, 4); - } - - /** - * Maintain RefHolder objects that will live in old generation. Each holder has ~1MB padding and a - * reference slot for young objects. - */ - private void maintainCrossRefHolders(int targetMB) { - long targetBytes = targetMB * 1024L * 1024L; - long currentBytes = crossRefBytesAllocated.get(); - - // Add holders if below target - while (currentBytes < targetBytes) { - RefHolder holder = new RefHolder(1024 * 1024); // ~1MB each - crossRefHolders.add(holder); - currentBytes += 1024 * 1024; - crossRefBytesAllocated.set(currentBytes); + + private void executeFragmentationScenario(AllocationMode mode) { + int targetMB = mode.getLiveSetSizeMB(); + maintainLiveSet(targetMB); + + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + allocateFragmentationGarbageMultiThreaded(bytesPerIteration, 4); } - // Remove holders if above target - while (currentBytes > targetBytes && !crossRefHolders.isEmpty()) { - crossRefHolders.removeFirst(); - currentBytes -= 1024 * 1024; - crossRefBytesAllocated.set(currentBytes); + private void executeCrossRefsScenario(AllocationMode mode) { + // Maintain old gen holders (these will be promoted after surviving GCs) + maintainCrossRefHolders(mode.getLiveSetSizeMB()); + + int rateMBPerSec = mode.getAllocationRateMBPerSec(); + int bytesPerIteration = (rateMBPerSec * 1024 * 1024) / 10; + + // Create young objects and link them from old gen holders + // This triggers G1's write barriers and remembered set updates + createCrossGenerationalRefsMultiThreaded(bytesPerIteration, 4); } - } - - /** - * Create young objects and update old→young references. Each reference update triggers G1's write - * barrier, which marks the card table and adds to remembered sets. This is the overhead we're - * testing - C4 has no remembered sets. - */ - private void createCrossGenerationalRefsMultiThreaded(int totalBytes, int numThreads) { - if (crossRefHolders.isEmpty()) { - return; + + /** + * Maintain RefHolder objects that will live in old generation. Each holder has ~1MB padding and a reference slot for young objects. + */ + private void maintainCrossRefHolders(int targetMB) { + long targetBytes = targetMB * 1024L * 1024L; + long currentBytes = crossRefBytesAllocated.get(); + + // Add holders if below target + while (currentBytes < targetBytes) { + RefHolder holder = new RefHolder(1024 * 1024); // ~1MB each + crossRefHolders.add(holder); + currentBytes += 1024 * 1024; + crossRefBytesAllocated.set(currentBytes); + } + + // Remove holders if above target + while (currentBytes > targetBytes && !crossRefHolders.isEmpty()) { + crossRefHolders.removeFirst(); + currentBytes -= 1024 * 1024; + crossRefBytesAllocated.set(currentBytes); + } } - int bytesPerThread = totalBytes / numThreads; - CompletableFuture[] futures = new CompletableFuture[numThreads]; + /** + * Create young objects and update old→young references. Each reference update triggers G1's write barrier, which marks the card table and adds to + * remembered sets. This is the overhead we're testing - C4 has no remembered sets. + */ + private void createCrossGenerationalRefsMultiThreaded(int totalBytes, int numThreads) { + if (crossRefHolders.isEmpty()) { + return; + } - // Convert to array for random access from multiple threads - RefHolder[] holders = crossRefHolders.toArray(new RefHolder[0]); + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; - for (int t = 0; t < numThreads; t++) { - futures[t] = - CompletableFuture.runAsync( - () -> { + // Convert to array for random access from multiple threads + RefHolder[] holders = crossRefHolders.toArray(new RefHolder[0]); + + for (int t = 0; t < numThreads; t++) { + futures[t] = CompletableFuture.runAsync(() -> { int remaining = bytesPerThread; while (remaining > 0) { - // Create young object (1-4KB each for variety) - int size = ThreadLocalRandom.current().nextInt(1024, 4097); - if (size > remaining) size = remaining; - byte[] youngObj = new byte[size]; - ThreadLocalRandom.current().nextBytes(youngObj); - - // Update random old gen holder to point to this young object - // This write triggers G1's post-write barrier: - // 1. Marks card table entry as dirty - // 2. Adds to remembered set for later scanning - int idx = ThreadLocalRandom.current().nextInt(holders.length); - holders[idx].youngRef = youngObj; - - remaining -= size; + // Create young object (1-4KB each for variety) + int size = ThreadLocalRandom.current().nextInt(1024, 4097); + if (size > remaining) + size = remaining; + byte[] youngObj = new byte[size]; + ThreadLocalRandom.current().nextBytes(youngObj); + + // Update random old gen holder to point to this young object + // This write triggers G1's post-write barrier: + // 1. Marks card table entry as dirty + // 2. Adds to remembered set for later scanning + int idx = ThreadLocalRandom.current().nextInt(holders.length); + holders[idx].youngRef = youngObj; + + remaining -= size; } totalBytesAllocated.addAndGet(bytesPerThread); - }, - executorService); - } + }, executorService); + } - CompletableFuture.allOf(futures).join(); - } + CompletableFuture.allOf(futures).join(); + } - private void allocateTransientGarbageMultiThreaded(int totalBytes, int numThreads) { - int bytesPerThread = totalBytes / numThreads; - CompletableFuture[] futures = new CompletableFuture[numThreads]; + private void allocateTransientGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; - for (int t = 0; t < numThreads; t++) { - futures[t] = - CompletableFuture.runAsync( - () -> { + for (int t = 0; t < numThreads; t++) { + futures[t] = CompletableFuture.runAsync(() -> { // Each thread allocates its share byte[] garbage = new byte[bytesPerThread]; ThreadLocalRandom.current().nextBytes(garbage); // Object is now eligible for GC totalBytesAllocated.addAndGet(bytesPerThread); - }, - executorService); - } + }, executorService); + } - // Wait for all threads to complete - CompletableFuture.allOf(futures).join(); - } + // Wait for all threads to complete + CompletableFuture.allOf(futures).join(); + } - private void allocatePromotableGarbageMultiThreaded(int totalBytes, int numThreads) { - int bytesPerThread = totalBytes / numThreads; - CompletableFuture[] futures = new CompletableFuture[numThreads]; + private void allocatePromotableGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; - for (int t = 0; t < numThreads; t++) { - futures[t] = - CompletableFuture.runAsync( - () -> { + for (int t = 0; t < numThreads; t++) { + futures[t] = CompletableFuture.runAsync(() -> { // Create objects that live long enough to be promoted byte[] obj = new byte[bytesPerThread]; ThreadLocalRandom.current().nextBytes(obj); promotableObjects.add(obj); totalBytesAllocated.addAndGet(bytesPerThread); - }, - executorService); - } + }, executorService); + } - CompletableFuture.allOf(futures).join(); - } + CompletableFuture.allOf(futures).join(); + } - private void allocateFragmentationGarbageMultiThreaded(int totalBytes, int numThreads) { - int bytesPerThread = totalBytes / numThreads; - CompletableFuture[] futures = new CompletableFuture[numThreads]; + private void allocateFragmentationGarbageMultiThreaded(int totalBytes, int numThreads) { + int bytesPerThread = totalBytes / numThreads; + CompletableFuture[] futures = new CompletableFuture[numThreads]; - for (int t = 0; t < numThreads; t++) { - futures[t] = - CompletableFuture.runAsync( - () -> { + for (int t = 0; t < numThreads; t++) { + futures[t] = CompletableFuture.runAsync(() -> { int remaining = bytesPerThread; while (remaining > 0) { - // Small objects 100-1000 bytes - int size = ThreadLocalRandom.current().nextInt(100, 1001); - if (size > remaining) size = remaining; - byte[] garbage = new byte[size]; - ThreadLocalRandom.current().nextBytes(garbage); - remaining -= size; + // Small objects 100-1000 bytes + int size = ThreadLocalRandom.current().nextInt(100, 1001); + if (size > remaining) + size = remaining; + byte[] garbage = new byte[size]; + ThreadLocalRandom.current().nextBytes(garbage); + remaining -= size; } totalBytesAllocated.addAndGet(bytesPerThread); - }, - executorService); - } - - CompletableFuture.allOf(futures).join(); - } + }, executorService); + } - private void maintainLiveSet(int targetMB) { - long targetBytes = targetMB * 1024L * 1024L; - long currentBytes = liveSetBytesAllocated.get(); - - // Add objects if below target - while (currentBytes < targetBytes) { - byte[] obj = new byte[1024 * 1024]; // 1 MB object - ThreadLocalRandom.current().nextBytes(obj); - liveSet.add(obj); - currentBytes += 1024 * 1024; - liveSetBytesAllocated.set(currentBytes); + CompletableFuture.allOf(futures).join(); } - // Remove objects if above target - while (currentBytes > targetBytes && !liveSet.isEmpty()) { - liveSet.removeFirst(); - currentBytes -= 1024 * 1024; - liveSetBytesAllocated.set(currentBytes); + private void maintainLiveSet(int targetMB) { + long targetBytes = targetMB * 1024L * 1024L; + long currentBytes = liveSetBytesAllocated.get(); + + // Add objects if below target + while (currentBytes < targetBytes) { + byte[] obj = new byte[1024 * 1024]; // 1 MB object + ThreadLocalRandom.current().nextBytes(obj); + liveSet.add(obj); + currentBytes += 1024 * 1024; + liveSetBytesAllocated.set(currentBytes); + } + + // Remove objects if above target + while (currentBytes > targetBytes && !liveSet.isEmpty()) { + liveSet.removeFirst(); + currentBytes -= 1024 * 1024; + liveSetBytesAllocated.set(currentBytes); + } } - } - private void logStats() { - long now = System.currentTimeMillis(); - if (now - lastStatsTime >= 5000) { - double elapsedSeconds = (now - lastStatsTime) / 1000.0; - long allocated = totalBytesAllocated.getAndSet(0); - double mbPerSec = (allocated / (1024.0 * 1024.0)) / elapsedSeconds; + private void logStats() { + long now = System.currentTimeMillis(); + if (now - lastStatsTime >= 5000) { + double elapsedSeconds = (now - lastStatsTime) / 1000.0; + long allocated = totalBytesAllocated.getAndSet(0); + double mbPerSec = (allocated / (1024.0 * 1024.0)) / elapsedSeconds; - LOGGER.info( - String.format( - "Memory Pressure Stats - Mode: %s | Allocated: %.2f MB/sec | Live Set: %d MB", - currentMode, mbPerSec, liveSetBytesAllocated.get() / (1024 * 1024))); + LOGGER.info(String.format("Memory Pressure Stats - Mode: %s | Allocated: %.2f MB/sec | Live Set: %d MB", currentMode, mbPerSec, + liveSetBytesAllocated.get() / (1024 * 1024))); - lastStatsTime = now; + lastStatsTime = now; + } } - } - @PreDestroy - public void shutdown() { - LOGGER.info("Shutting down MemoryPressureService"); - stopPressure(); - } + @PreDestroy + public void shutdown() { + LOGGER.info("Shutting down MemoryPressureService"); + stopPressure(); + } - public AllocationMode getCurrentMode() { - return currentMode; - } + public AllocationMode getCurrentMode() { + return currentMode; + } - public boolean isRunning() { - return running; - } + public boolean isRunning() { + return running; + } } diff --git a/src/main/java/fish/payara/trader/pressure/ScenarioType.java b/src/main/java/fish/payara/trader/pressure/ScenarioType.java index cc62cc2..4bb8969 100644 --- a/src/main/java/fish/payara/trader/pressure/ScenarioType.java +++ b/src/main/java/fish/payara/trader/pressure/ScenarioType.java @@ -1,10 +1,5 @@ package fish.payara.trader.pressure; public enum ScenarioType { - NONE, - STEADY, - GROWING, - PROMOTION, - FRAGMENTATION, - CROSS_REF + NONE, STEADY, GROWING, PROMOTION, FRAGMENTATION, CROSS_REF } diff --git a/src/main/java/fish/payara/trader/rest/ApplicationConfig.java b/src/main/java/fish/payara/trader/rest/ApplicationConfig.java index 22bacc1..d668bd9 100644 --- a/src/main/java/fish/payara/trader/rest/ApplicationConfig.java +++ b/src/main/java/fish/payara/trader/rest/ApplicationConfig.java @@ -4,4 +4,5 @@ import jakarta.ws.rs.core.Application; @ApplicationPath("/api") -public class ApplicationConfig extends Application {} +public class ApplicationConfig extends Application { +} diff --git a/src/main/java/fish/payara/trader/rest/GCStatsResource.java b/src/main/java/fish/payara/trader/rest/GCStatsResource.java index a914331..7018040 100644 --- a/src/main/java/fish/payara/trader/rest/GCStatsResource.java +++ b/src/main/java/fish/payara/trader/rest/GCStatsResource.java @@ -3,11 +3,17 @@ import fish.payara.trader.aeron.MarketDataPublisher; import fish.payara.trader.gc.GCStats; import fish.payara.trader.gc.GCStatsService; +import fish.payara.trader.monitoring.GCPauseMonitor; +import fish.payara.trader.monitoring.SLAMonitorService; import fish.payara.trader.pressure.MemoryPressureService; import jakarta.inject.Inject; -import jakarta.ws.rs.*; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; + import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.util.HashMap; @@ -20,115 +26,116 @@ @Path("/gc") public class GCStatsResource { - private static final Logger LOGGER = Logger.getLogger(GCStatsResource.class.getName()); + private static final Logger LOGGER = Logger.getLogger(GCStatsResource.class.getName()); + + @Inject + private GCStatsService gcStatsService; - @Inject private GCStatsService gcStatsService; + @Inject + private MemoryPressureService memoryPressureService; - @Inject private MemoryPressureService memoryPressureService; + @Inject + private MarketDataPublisher publisher; - @Inject private MarketDataPublisher publisher; + @Inject + private SLAMonitorService slaMonitor; - @Inject private fish.payara.trader.monitoring.SLAMonitorService slaMonitor; + @Inject + private GCPauseMonitor gcPauseMonitor; - @Inject private fish.payara.trader.monitoring.GCPauseMonitor gcPauseMonitor; + @GET + @Path("/sla") + @Produces(MediaType.APPLICATION_JSON) + public Response getSLAStats() { + return Response.ok(slaMonitor.getStats()).build(); + } - @GET - @Path("/sla") - @Produces(MediaType.APPLICATION_JSON) - public Response getSLAStats() { - return Response.ok(slaMonitor.getStats()).build(); - } + @POST + @Path("/sla/reset") + public Response resetSLAStats() { + slaMonitor.reset(); + return Response.ok(Map.of("status", "reset")).build(); + } - @POST - @Path("/sla/reset") - public Response resetSLAStats() { - slaMonitor.reset(); - return Response.ok(Map.of("status", "reset")).build(); - } + @GET + @Path("/pauses") + @Produces(MediaType.APPLICATION_JSON) + public Response getGCPauseStats() { + return Response.ok(gcPauseMonitor.getStats()).build(); + } - @GET - @Path("/pauses") - @Produces(MediaType.APPLICATION_JSON) - public Response getGCPauseStats() { - return Response.ok(gcPauseMonitor.getStats()).build(); - } + @POST + @Path("/pauses/reset") + public Response resetGCPauseStats() { + gcPauseMonitor.reset(); + return Response.ok(Map.of("status", "reset")).build(); + } - @POST - @Path("/pauses/reset") - public Response resetGCPauseStats() { - gcPauseMonitor.reset(); - return Response.ok(Map.of("status", "reset")).build(); - } + @GET + @Path("/comparison") + @Produces(MediaType.APPLICATION_JSON) + public Response getComparison() { + Map comparison = new HashMap<>(); + + // Identify which instance is responding + String instanceName = System.getenv("PAYARA_INSTANCE_NAME"); + if (instanceName == null) { + instanceName = "standalone"; + } + comparison.put("instanceName", instanceName); + + String jvmVendor = System.getProperty("java.vm.vendor"); + String jvmName = System.getProperty("java.vm.name"); + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + String gcName = gcBeans.stream().map(GarbageCollectorMXBean::getName).collect(Collectors.joining(", ")); + + boolean isAzulC4 = gcName.toLowerCase().contains("c4") || jvmName.toLowerCase().contains("zing"); + + comparison.put("jvmVendor", jvmVendor); + comparison.put("jvmName", jvmName); + comparison.put("gcCollectors", gcName); + comparison.put("isAzulC4", isAzulC4); + comparison.put("heapSizeMB", Runtime.getRuntime().maxMemory() / (1024 * 1024)); + comparison.put("allocationMode", memoryPressureService.getCurrentMode()); + comparison.put("allocationRateMBps", memoryPressureService.getCurrentMode().getAllocationRateMBPerSec()); + comparison.put("messageRate", publisher.getMessagesPublished()); + + List stats = gcStatsService.collectGCStats(); + comparison.put("gcStats", stats); + + fish.payara.trader.monitoring.GCPauseMonitor.GCPauseStats pauseStats = gcPauseMonitor.getStats(); + comparison.put("pauseP50Ms", pauseStats.p50Ms); + comparison.put("pauseP95Ms", pauseStats.p95Ms); + comparison.put("pauseP99Ms", pauseStats.p99Ms); + comparison.put("pauseP999Ms", pauseStats.p999Ms); + comparison.put("pauseMaxMs", pauseStats.maxMs); // All-time max + comparison.put("pauseAvgMs", pauseStats.avgPauseMs); + comparison.put("totalPauseCount", pauseStats.totalPauseCount); + comparison.put("totalPauseTimeMs", pauseStats.totalPauseTimeMs); + + comparison.put("slaViolations10ms", pauseStats.violationsOver10ms); + comparison.put("slaViolations50ms", pauseStats.violationsOver50ms); + comparison.put("slaViolations100ms", pauseStats.violationsOver100ms); + comparison.put("pauseSampleSize", pauseStats.sampleSize); + + return Response.ok(comparison).build(); + } - @GET - @Path("/comparison") - @Produces(MediaType.APPLICATION_JSON) - public Response getComparison() { - Map comparison = new HashMap<>(); + @GET + @Path("/stats") + @Produces(MediaType.APPLICATION_JSON) + public Response getGCStats() { + List stats = gcStatsService.collectGCStats(); + LOGGER.info(String.format("GET /api/gc/stats - Returned %d GC collector stats", stats.size())); + return Response.ok(stats).build(); + } - // Identify which instance is responding - String instanceName = System.getenv("PAYARA_INSTANCE_NAME"); - if (instanceName == null) { - instanceName = "standalone"; + @POST + @Path("/reset") + @Produces(MediaType.APPLICATION_JSON) + public Response resetStats() { + LOGGER.info("POST /api/gc/reset - Resetting GC statistics"); + gcStatsService.resetStats(); + return Response.ok().entity("{\"status\":\"reset\"}").build(); } - comparison.put("instanceName", instanceName); - - String jvmVendor = System.getProperty("java.vm.vendor"); - String jvmName = System.getProperty("java.vm.name"); - List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); - String gcName = - gcBeans.stream().map(GarbageCollectorMXBean::getName).collect(Collectors.joining(", ")); - - boolean isAzulC4 = - gcName.toLowerCase().contains("c4") || jvmName.toLowerCase().contains("zing"); - - comparison.put("jvmVendor", jvmVendor); - comparison.put("jvmName", jvmName); - comparison.put("gcCollectors", gcName); - comparison.put("isAzulC4", isAzulC4); - comparison.put("heapSizeMB", Runtime.getRuntime().maxMemory() / (1024 * 1024)); - comparison.put("allocationMode", memoryPressureService.getCurrentMode()); - comparison.put( - "allocationRateMBps", memoryPressureService.getCurrentMode().getAllocationRateMBPerSec()); - comparison.put("messageRate", publisher.getMessagesPublished()); - - List stats = gcStatsService.collectGCStats(); - comparison.put("gcStats", stats); - - fish.payara.trader.monitoring.GCPauseMonitor.GCPauseStats pauseStats = - gcPauseMonitor.getStats(); - comparison.put("pauseP50Ms", pauseStats.p50Ms); - comparison.put("pauseP95Ms", pauseStats.p95Ms); - comparison.put("pauseP99Ms", pauseStats.p99Ms); - comparison.put("pauseP999Ms", pauseStats.p999Ms); - comparison.put("pauseMaxMs", pauseStats.maxMs); // All-time max - comparison.put("pauseAvgMs", pauseStats.avgPauseMs); - comparison.put("totalPauseCount", pauseStats.totalPauseCount); - comparison.put("totalPauseTimeMs", pauseStats.totalPauseTimeMs); - - comparison.put("slaViolations10ms", pauseStats.violationsOver10ms); - comparison.put("slaViolations50ms", pauseStats.violationsOver50ms); - comparison.put("slaViolations100ms", pauseStats.violationsOver100ms); - comparison.put("pauseSampleSize", pauseStats.sampleSize); - - return Response.ok(comparison).build(); - } - - @GET - @Path("/stats") - @Produces(MediaType.APPLICATION_JSON) - public Response getGCStats() { - List stats = gcStatsService.collectGCStats(); - LOGGER.info(String.format("GET /api/gc/stats - Returned %d GC collector stats", stats.size())); - return Response.ok(stats).build(); - } - - @POST - @Path("/reset") - @Produces(MediaType.APPLICATION_JSON) - public Response resetStats() { - LOGGER.info("POST /api/gc/reset - Resetting GC statistics"); - gcStatsService.resetStats(); - return Response.ok().entity("{\"status\":\"reset\"}").build(); - } } diff --git a/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java b/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java index be0d1ad..9fc49a7 100644 --- a/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java +++ b/src/main/java/fish/payara/trader/rest/MemoryPressureResource.java @@ -13,81 +13,79 @@ @Path("/pressure") public class MemoryPressureResource { - private static final Logger LOGGER = Logger.getLogger(MemoryPressureResource.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MemoryPressureResource.class.getName()); - @Inject private MemoryPressureService pressureService; + @Inject + private MemoryPressureService pressureService; - @GET - @Path("/status") - @Produces(MediaType.APPLICATION_JSON) - public Response getStatus() { - AllocationMode currentMode = pressureService.getCurrentMode(); + @GET + @Path("/status") + @Produces(MediaType.APPLICATION_JSON) + public Response getStatus() { + AllocationMode currentMode = pressureService.getCurrentMode(); - Map status = new HashMap<>(); - status.put("currentMode", currentMode.name()); - status.put("description", currentMode.getDescription()); - status.put("running", pressureService.isRunning()); - status.put("allocationRateMBPerSec", currentMode.getAllocationRateMBPerSec()); - status.put("liveSetSizeMB", currentMode.getLiveSetSizeMB()); - status.put("scenarioType", currentMode.getScenarioType()); - return Response.ok(status).build(); - } + Map status = new HashMap<>(); + status.put("currentMode", currentMode.name()); + status.put("description", currentMode.getDescription()); + status.put("running", pressureService.isRunning()); + status.put("allocationRateMBPerSec", currentMode.getAllocationRateMBPerSec()); + status.put("liveSetSizeMB", currentMode.getLiveSetSizeMB()); + status.put("scenarioType", currentMode.getScenarioType()); + return Response.ok(status).build(); + } - @POST - @Path("/mode/{mode}") - @Produces(MediaType.APPLICATION_JSON) - public Response setMode(@PathParam("mode") String modeStr) { - try { - AllocationMode mode = AllocationMode.valueOf(modeStr.toUpperCase()); - LOGGER.info( - String.format( - "POST /api/pressure/mode/%s - Setting memory pressure mode to: %s", - modeStr, mode.name())); + @POST + @Path("/mode/{mode}") + @Produces(MediaType.APPLICATION_JSON) + public Response setMode(@PathParam("mode") String modeStr) { + try { + AllocationMode mode = AllocationMode.valueOf(modeStr.toUpperCase()); + LOGGER.info(String.format("POST /api/pressure/mode/%s - Setting memory pressure mode to: %s", modeStr, mode.name())); - pressureService.setAllocationMode(mode); + pressureService.setAllocationMode(mode); - Map result = new HashMap<>(); - result.put("success", true); - result.put("mode", mode.name()); - result.put("description", mode.getDescription()); - result.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); - result.put("scenarioType", mode.getScenarioType()); + Map result = new HashMap<>(); + result.put("success", true); + result.put("mode", mode.name()); + result.put("description", mode.getDescription()); + result.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); + result.put("scenarioType", mode.getScenarioType()); - return Response.ok(result).build(); - } catch (IllegalArgumentException e) { - LOGGER.warning(String.format("POST /api/pressure/mode/%s - Invalid mode requested", modeStr)); + return Response.ok(result).build(); + } catch (IllegalArgumentException e) { + LOGGER.warning(String.format("POST /api/pressure/mode/%s - Invalid mode requested", modeStr)); - Map error = new HashMap<>(); - error.put("success", false); - error.put("error", "Invalid mode: " + modeStr); - // Valid modes are all values of AllocationMode - StringBuilder validModes = new StringBuilder(); - for (AllocationMode m : AllocationMode.values()) { - validModes.append(m.name()).append(", "); - } - error.put("validModes", validModes.toString()); - return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); + Map error = new HashMap<>(); + error.put("success", false); + error.put("error", "Invalid mode: " + modeStr); + // Valid modes are all values of AllocationMode + StringBuilder validModes = new StringBuilder(); + for (AllocationMode m : AllocationMode.values()) { + validModes.append(m.name()).append(", "); + } + error.put("validModes", validModes.toString()); + return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); + } } - } - @GET - @Path("/modes") - @Produces(MediaType.APPLICATION_JSON) - public Response getModes() { - LOGGER.fine("GET /api/pressure/modes - Listing all allocation modes"); + @GET + @Path("/modes") + @Produces(MediaType.APPLICATION_JSON) + public Response getModes() { + LOGGER.fine("GET /api/pressure/modes - Listing all allocation modes"); - Map> modes = new HashMap<>(); + Map> modes = new HashMap<>(); - for (AllocationMode mode : AllocationMode.values()) { - Map modeInfo = new HashMap<>(); - modeInfo.put("name", mode.name()); - modeInfo.put("description", mode.getDescription()); - modeInfo.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); - modeInfo.put("liveSetSizeMB", mode.getLiveSetSizeMB()); - modeInfo.put("scenarioType", mode.getScenarioType()); - modes.put(mode.name(), modeInfo); - } + for (AllocationMode mode : AllocationMode.values()) { + Map modeInfo = new HashMap<>(); + modeInfo.put("name", mode.name()); + modeInfo.put("description", mode.getDescription()); + modeInfo.put("allocationRateMBPerSec", mode.getAllocationRateMBPerSec()); + modeInfo.put("liveSetSizeMB", mode.getLiveSetSizeMB()); + modeInfo.put("scenarioType", mode.getScenarioType()); + modes.put(mode.name(), modeInfo); + } - return Response.ok(modes).build(); - } + return Response.ok(modes).build(); + } } diff --git a/src/main/java/fish/payara/trader/rest/StatusResource.java b/src/main/java/fish/payara/trader/rest/StatusResource.java index 46b895c..84ae1c8 100644 --- a/src/main/java/fish/payara/trader/rest/StatusResource.java +++ b/src/main/java/fish/payara/trader/rest/StatusResource.java @@ -18,79 +18,78 @@ @Path("/status") public class StatusResource { - @Inject private AeronSubscriberBean subscriber; + @Inject + private AeronSubscriberBean subscriber; - @Inject private MarketDataPublisher publisher; + @Inject + private MarketDataPublisher publisher; - @Inject private MarketDataBroadcaster broadcaster; + @Inject + private MarketDataBroadcaster broadcaster; - @Inject private HazelcastInstance hazelcastInstance; + @Inject + private HazelcastInstance hazelcastInstance; - @GET - @Produces(MediaType.APPLICATION_JSON) - public Response getStatus() { - Map status = new HashMap<>(); + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getStatus() { + Map status = new HashMap<>(); - String instanceName = System.getenv("PAYARA_INSTANCE_NAME"); - if (instanceName == null) { - instanceName = "standalone"; + String instanceName = System.getenv("PAYARA_INSTANCE_NAME"); + if (instanceName == null) { + instanceName = "standalone"; + } + + status.put("application", "TradeStreamEE"); + status.put("description", "High-frequency trading dashboard with Aeron and SBE"); + status.put("instance", instanceName); + status.put("subscriber", subscriber.getStatus()); + + // Include both local and cluster-wide message counts + Map publisherStats = new HashMap<>(); + publisherStats.put("localMessagesPublished", publisher.getMessagesPublished()); + publisherStats.put("clusterMessagesPublished", publisher.getClusterMessagesPublished()); + status.put("publisher", publisherStats); + + status.put("websocket", Map.of("activeSessions", broadcaster.getSessionCount())); + status.put("status", "UP"); + + return Response.ok(status).build(); } - status.put("application", "TradeStreamEE"); - status.put("description", "High-frequency trading dashboard with Aeron and SBE"); - status.put("instance", instanceName); - status.put("subscriber", subscriber.getStatus()); - - // Include both local and cluster-wide message counts - Map publisherStats = new HashMap<>(); - publisherStats.put("localMessagesPublished", publisher.getMessagesPublished()); - publisherStats.put("clusterMessagesPublished", publisher.getClusterMessagesPublished()); - status.put("publisher", publisherStats); - - status.put("websocket", Map.of("activeSessions", broadcaster.getSessionCount())); - status.put("status", "UP"); - - return Response.ok(status).build(); - } - - /** Get cluster status and membership information */ - @GET - @Path("/cluster") - @Produces(MediaType.APPLICATION_JSON) - public Response getClusterStatus() { - Map clusterInfo = new HashMap<>(); - - try { - if (hazelcastInstance == null) { - clusterInfo.put("clustered", false); - clusterInfo.put("message", "Running in standalone mode (Hazelcast not available)"); - return Response.ok(clusterInfo).build(); - } - - clusterInfo.put("clustered", true); - clusterInfo.put("clusterSize", hazelcastInstance.getCluster().getMembers().size()); - clusterInfo.put("clusterTime", hazelcastInstance.getCluster().getClusterTime()); - clusterInfo.put( - "localMemberUuid", hazelcastInstance.getCluster().getLocalMember().getUuid().toString()); - - clusterInfo.put( - "members", - hazelcastInstance.getCluster().getMembers().stream() - .map( - member -> - Map.of( - "address", member.getAddress().toString(), - "uuid", member.getUuid().toString(), - "localMember", member.localMember(), - "liteMember", member.isLiteMember())) - .collect(Collectors.toList())); - - return Response.ok(clusterInfo).build(); - - } catch (Exception e) { - clusterInfo.put("clustered", false); - clusterInfo.put("error", e.getMessage()); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(clusterInfo).build(); + /** Get cluster status and membership information */ + @GET + @Path("/cluster") + @Produces(MediaType.APPLICATION_JSON) + public Response getClusterStatus() { + Map clusterInfo = new HashMap<>(); + + try { + if (hazelcastInstance == null) { + clusterInfo.put("clustered", false); + clusterInfo.put("message", "Running in standalone mode (Hazelcast not available)"); + return Response.ok(clusterInfo).build(); + } + + clusterInfo.put("clustered", true); + clusterInfo.put("clusterSize", hazelcastInstance.getCluster().getMembers().size()); + clusterInfo.put("clusterTime", hazelcastInstance.getCluster().getClusterTime()); + clusterInfo.put("localMemberUuid", hazelcastInstance.getCluster().getLocalMember().getUuid().toString()); + + clusterInfo.put("members", + hazelcastInstance.getCluster() + .getMembers() + .stream() + .map(member -> Map.of("address", member.getAddress().toString(), "uuid", member.getUuid().toString(), "localMember", + member.localMember(), "liteMember", member.isLiteMember())) + .collect(Collectors.toList())); + + return Response.ok(clusterInfo).build(); + + } catch (Exception e) { + clusterInfo.put("clustered", false); + clusterInfo.put("error", e.getMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(clusterInfo).build(); + } } - } } diff --git a/src/main/java/fish/payara/trader/websocket/MarketDataBroadcaster.java b/src/main/java/fish/payara/trader/websocket/MarketDataBroadcaster.java index 5dd4370..40e43d3 100644 --- a/src/main/java/fish/payara/trader/websocket/MarketDataBroadcaster.java +++ b/src/main/java/fish/payara/trader/websocket/MarketDataBroadcaster.java @@ -14,169 +14,162 @@ /** * Broadcaster for market data WebSocket messages. * - *

    Maintains a set of active WebSocket sessions and broadcasts JSON messages to all connected - * clients. + *

    + * Maintains a set of active WebSocket sessions and broadcasts JSON messages to all connected clients. * - *

    In clustered mode, uses Hazelcast distributed topics to broadcast messages across all cluster - * members, ensuring all WebSocket clients receive data regardless of which instance they connect - * to. + *

    + * In clustered mode, uses Hazelcast distributed topics to broadcast messages across all cluster members, ensuring all WebSocket clients receive data regardless + * of which instance they connect to. * - *

    Note: JSON string creation intentionally generates garbage to stress-test Azul's Pauseless GC - * (C4). + *

    + * Note: JSON string creation intentionally generates garbage to stress-test Azul's Pauseless GC (C4). */ @ApplicationScoped public class MarketDataBroadcaster { - private static final Logger LOGGER = Logger.getLogger(MarketDataBroadcaster.class.getName()); - private static final String TOPIC_NAME = "market-data-broadcast"; - - private final Set sessions = ConcurrentHashMap.newKeySet(); - - @Inject private HazelcastInstance hazelcastInstance; - - @Inject private fish.payara.trader.monitoring.SLAMonitorService slaMonitor; - - private ITopic clusterTopic; - - // Statistics - private long messagesSent = 0; - private long lastStatsTime = System.currentTimeMillis(); - - /** Initialize Hazelcast topic subscription for cluster-wide broadcasting */ - @PostConstruct - public void init() { - try { - if (hazelcastInstance != null) { - clusterTopic = hazelcastInstance.getTopic(TOPIC_NAME); - clusterTopic.addMessageListener( - message -> { - broadcastLocal(message.getMessageObject()); - }); - LOGGER.info("Subscribed to Hazelcast topic: " + TOPIC_NAME + " (clustered mode)"); - } else { - LOGGER.info("Hazelcast not available - running in standalone mode"); - } - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to initialize Hazelcast topic subscription", e); - // Continue without clustering + private static final Logger LOGGER = Logger.getLogger(MarketDataBroadcaster.class.getName()); + private static final String TOPIC_NAME = "market-data-broadcast"; + + private final Set sessions = ConcurrentHashMap.newKeySet(); + + @Inject + private HazelcastInstance hazelcastInstance; + + @Inject + private fish.payara.trader.monitoring.SLAMonitorService slaMonitor; + + private ITopic clusterTopic; + + // Statistics + private long messagesSent = 0; + private long lastStatsTime = System.currentTimeMillis(); + + /** Initialize Hazelcast topic subscription for cluster-wide broadcasting */ + @PostConstruct + public void init() { + try { + if (hazelcastInstance != null) { + clusterTopic = hazelcastInstance.getTopic(TOPIC_NAME); + clusterTopic.addMessageListener(message -> { + broadcastLocal(message.getMessageObject()); + }); + LOGGER.info("Subscribed to Hazelcast topic: " + TOPIC_NAME + " (clustered mode)"); + } else { + LOGGER.info("Hazelcast not available - running in standalone mode"); + } + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to initialize Hazelcast topic subscription", e); + // Continue without clustering + } } - } - - /** Register a new WebSocket session */ - public void addSession(Session session) { - sessions.add(session); - LOGGER.info("WebSocket session added. Total sessions: " + sessions.size()); - } - - public void removeSession(Session session) { - sessions.remove(session); - LOGGER.info("WebSocket session removed. Total sessions: " + sessions.size()); - } - - /** - * Broadcast JSON message to all connected clients across the cluster. - * - *

    In clustered mode, publishes to Hazelcast topic which distributes to all cluster members. - * Each member then broadcasts to its local WebSocket sessions. - * - *

    In standalone mode, broadcasts directly to local sessions. - * - *

    This method intentionally creates string allocations to generate garbage and stress the - * garbage collector. - */ - public void broadcast(String jsonMessage) { - if (clusterTopic != null) { - try { - clusterTopic.publish(jsonMessage); - } catch (Exception e) { - LOGGER.log( - Level.SEVERE, - "Failed to publish to Hazelcast topic, falling back to local broadcast", - e); - broadcastLocal(jsonMessage); - } - } else { - broadcastLocal(jsonMessage); + + /** Register a new WebSocket session */ + public void addSession(Session session) { + sessions.add(session); + LOGGER.info("WebSocket session added. Total sessions: " + sessions.size()); } - } - - /** - * Broadcast message to local WebSocket sessions only. Called either in standalone mode or by - * Hazelcast topic listener. - */ - private void broadcastLocal(String jsonMessage) { - if (sessions.isEmpty()) { - return; + + public void removeSession(Session session) { + sessions.remove(session); + LOGGER.info("WebSocket session removed. Total sessions: " + sessions.size()); } - long startTime = System.currentTimeMillis(); - - sessions.removeIf( - session -> { - if (!session.isOpen()) { - return true; - } - try { - session.getAsyncRemote().sendText(jsonMessage); - return false; - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to send message", e); - return true; - } + /** + * Broadcast JSON message to all connected clients across the cluster. + * + *

    + * In clustered mode, publishes to Hazelcast topic which distributes to all cluster members. Each member then broadcasts to its local WebSocket sessions. + * + *

    + * In standalone mode, broadcasts directly to local sessions. + * + *

    + * This method intentionally creates string allocations to generate garbage and stress the garbage collector. + */ + public void broadcast(String jsonMessage) { + if (clusterTopic != null) { + try { + clusterTopic.publish(jsonMessage); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to publish to Hazelcast topic, falling back to local broadcast", e); + broadcastLocal(jsonMessage); + } + } else { + broadcastLocal(jsonMessage); + } + } + + /** + * Broadcast message to local WebSocket sessions only. Called either in standalone mode or by Hazelcast topic listener. + */ + private void broadcastLocal(String jsonMessage) { + if (sessions.isEmpty()) { + return; + } + + long startTime = System.currentTimeMillis(); + + sessions.removeIf(session -> { + if (!session.isOpen()) { + return true; + } + try { + session.getAsyncRemote().sendText(jsonMessage); + return false; + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to send message", e); + return true; + } }); - long latency = System.currentTimeMillis() - startTime; - if (slaMonitor != null) { - slaMonitor.recordOperation(latency); + long latency = System.currentTimeMillis() - startTime; + if (slaMonitor != null) { + slaMonitor.recordOperation(latency); + } + + logStatistics(); + } + + /** + * Broadcast to all clients with additional garbage generation for GC stress. + * + *

    + * This method wraps the original message in a larger JSON envelope with padding. This increases both memory allocation (String construction) and network + * bandwidth usage, simulating a heavier protocol or inefficient data packaging. + */ + public void broadcastWithArtificialLoad(String jsonMessage) { + String padding = "X".repeat(1024); + + // Wrap the original message in a new JSON structure + // We use StringBuilder to explicitly construct the new JSON string + String enrichedMessage = new StringBuilder(jsonMessage.length() + padding.length() + 100).append("{\"wrapped\":true,") + .append("\"timestamp\":") + .append(System.nanoTime()) + .append(",") + .append("\"padding\":\"") + .append(padding) + .append("\",") + .append("\"data\":") + .append(jsonMessage) + .append("}") + .toString(); + + broadcast(enrichedMessage); + } + + /** Get count of active sessions */ + public int getSessionCount() { + return sessions.size(); } - logStatistics(); - } - - /** - * Broadcast to all clients with additional garbage generation for GC stress. - * - *

    This method wraps the original message in a larger JSON envelope with padding. This - * increases both memory allocation (String construction) and network bandwidth usage, simulating - * a heavier protocol or inefficient data packaging. - */ - public void broadcastWithArtificialLoad(String jsonMessage) { - String padding = "X".repeat(1024); - - // Wrap the original message in a new JSON structure - // We use StringBuilder to explicitly construct the new JSON string - String enrichedMessage = - new StringBuilder(jsonMessage.length() + padding.length() + 100) - .append("{\"wrapped\":true,") - .append("\"timestamp\":") - .append(System.nanoTime()) - .append(",") - .append("\"padding\":\"") - .append(padding) - .append("\",") - .append("\"data\":") - .append(jsonMessage) - .append("}") - .toString(); - - broadcast(enrichedMessage); - } - - /** Get count of active sessions */ - public int getSessionCount() { - return sessions.size(); - } - - /** Log statistics periodically */ - private void logStatistics() { - long now = System.currentTimeMillis(); - if (now - lastStatsTime > 10000) { // Log every 10 seconds - LOGGER.info( - String.format( - "WebSocket Stats - Active sessions: %d, Messages sent: %,d (%.1f msg/sec)", - sessions.size(), messagesSent, messagesSent / ((now - lastStatsTime) / 1000.0))); - lastStatsTime = now; - messagesSent = 0; + /** Log statistics periodically */ + private void logStatistics() { + long now = System.currentTimeMillis(); + if (now - lastStatsTime > 10000) { // Log every 10 seconds + LOGGER.info(String.format("WebSocket Stats - Active sessions: %d, Messages sent: %,d (%.1f msg/sec)", sessions.size(), messagesSent, + messagesSent / ((now - lastStatsTime) / 1000.0))); + lastStatsTime = now; + messagesSent = 0; + } } - } } diff --git a/src/main/java/fish/payara/trader/websocket/MarketDataWebSocket.java b/src/main/java/fish/payara/trader/websocket/MarketDataWebSocket.java index c1978e6..2a4840e 100644 --- a/src/main/java/fish/payara/trader/websocket/MarketDataWebSocket.java +++ b/src/main/java/fish/payara/trader/websocket/MarketDataWebSocket.java @@ -10,60 +10,55 @@ /** * WebSocket endpoint for streaming market data to clients. * - *

    Clients connect to ws://host:port/context/market-data and receive real-time JSON market data - * updates. + *

    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�&rDw1HjRfbuIQN_yHU_GP?)^I= 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Ì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

    + * Clients connect to ws://host:port/context/market-data and receive real-time JSON market data updates. */ @ServerEndpoint("/market-data") public class MarketDataWebSocket { - private static final Logger LOGGER = Logger.getLogger(MarketDataWebSocket.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MarketDataWebSocket.class.getName()); - @Inject private MarketDataBroadcaster broadcaster; + @Inject + private MarketDataBroadcaster broadcaster; - @Inject - @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") - private String ingestionMode; + @Inject + @ConfigProperty(name = "TRADER_INGESTION_MODE", defaultValue = "AERON") + private String ingestionMode; - @OnOpen - public void onOpen(Session session) { - LOGGER.info("WebSocket connection opened: " + session.getId()); - broadcaster.addSession(session); + @OnOpen + public void onOpen(Session session) { + LOGGER.info("WebSocket connection opened: " + session.getId()); + broadcaster.addSession(session); - try { - String welcomeJson = - String.format( - "{\"type\":\"info\",\"message\":\"Connected to TradeStreamEE market data feed\",\"mode\":\"%s\"}", - ingestionMode); - session.getBasicRemote().sendText(welcomeJson); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to send welcome message", e); + try { + String welcomeJson = String.format("{\"type\":\"info\",\"message\":\"Connected to TradeStreamEE market data feed\",\"mode\":\"%s\"}", + ingestionMode); + session.getBasicRemote().sendText(welcomeJson); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to send welcome message", e); + } } - } - @OnClose - public void onClose(Session session, CloseReason closeReason) { - LOGGER.info( - "WebSocket connection closed: " - + session.getId() - + ", reason: " - + closeReason.getReasonPhrase()); - broadcaster.removeSession(session); - } + @OnClose + public void onClose(Session session, CloseReason closeReason) { + LOGGER.info("WebSocket connection closed: " + session.getId() + ", reason: " + closeReason.getReasonPhrase()); + broadcaster.removeSession(session); + } - @OnError - public void onError(Session session, Throwable throwable) { - LOGGER.log(Level.WARNING, "WebSocket error for session: " + session.getId(), throwable); - broadcaster.removeSession(session); - } + @OnError + public void onError(Session session, Throwable throwable) { + LOGGER.log(Level.WARNING, "WebSocket error for session: " + session.getId(), throwable); + broadcaster.removeSession(session); + } - @OnMessage - public void onMessage(String message, Session session) { - LOGGER.fine("Received message from client: " + message); + @OnMessage + public void onMessage(String message, Session session) { + LOGGER.fine("Received message from client: " + message); - try { - session.getBasicRemote().sendText("{\"type\":\"ack\",\"message\":\"Message received\"}"); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to send acknowledgment", e); + try { + session.getBasicRemote().sendText("{\"type\":\"ack\",\"message\":\"Message received\"}"); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to send acknowledgment", e); + } } - } } diff --git a/src/test/java/fish/payara/trader/BasicFunctionalityTest.java b/src/test/java/fish/payara/trader/BasicFunctionalityTest.java index afa5100..3e97c9c 100644 --- a/src/test/java/fish/payara/trader/BasicFunctionalityTest.java +++ b/src/test/java/fish/payara/trader/BasicFunctionalityTest.java @@ -12,75 +12,73 @@ @DisplayName("Basic Functionality Tests") class BasicFunctionalityTest { - @Test - @DisplayName("Should verify allocation modes work correctly") - void shouldVerifyAllocationModesWorkCorrectly() { - // Test AllocationMode enum - assertEquals(AllocationMode.OFF, AllocationMode.valueOf("OFF")); - assertEquals(AllocationMode.STEADY_LOAD, AllocationMode.valueOf("STEADY_LOAD")); - assertEquals(AllocationMode.GROWING_HEAP, AllocationMode.valueOf("GROWING_HEAP")); - assertEquals(AllocationMode.PROMOTION_STORM, AllocationMode.valueOf("PROMOTION_STORM")); - assertEquals(AllocationMode.FRAGMENTATION, AllocationMode.valueOf("FRAGMENTATION")); + @Test + @DisplayName("Should verify allocation modes work correctly") + void shouldVerifyAllocationModesWorkCorrectly() { + // Test AllocationMode enum + assertEquals(AllocationMode.OFF, AllocationMode.valueOf("OFF")); + assertEquals(AllocationMode.STEADY_LOAD, AllocationMode.valueOf("STEADY_LOAD")); + assertEquals(AllocationMode.GROWING_HEAP, AllocationMode.valueOf("GROWING_HEAP")); + assertEquals(AllocationMode.PROMOTION_STORM, AllocationMode.valueOf("PROMOTION_STORM")); + assertEquals(AllocationMode.FRAGMENTATION, AllocationMode.valueOf("FRAGMENTATION")); - // Test allocation rates - assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); - assertTrue(AllocationMode.STEADY_LOAD.getAllocationRateMBPerSec() > 0); - // Note: STEADY_LOAD rate (200) is > OFF (0) - } + // Test allocation rates + assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); + assertTrue(AllocationMode.STEADY_LOAD.getAllocationRateMBPerSec() > 0); + // Note: STEADY_LOAD rate (200) is > OFF (0) + } - @Test - @DisplayName("Should initialize memory pressure service without CDI") - void shouldInitializeMemoryPressureServiceWithoutCDI() { - MemoryPressureService service = new MemoryPressureService(); - service.init(); + @Test + @DisplayName("Should initialize memory pressure service without CDI") + void shouldInitializeMemoryPressureServiceWithoutCDI() { + MemoryPressureService service = new MemoryPressureService(); + service.init(); - // Can't test mode changes without CDI injection, but can verify initialization - assertNotNull(service); - assertEquals(AllocationMode.OFF, service.getCurrentMode()); // Default should be OFF - } + // Can't test mode changes without CDI injection, but can verify initialization + assertNotNull(service); + assertEquals(AllocationMode.OFF, service.getCurrentMode()); // Default should be OFF + } - @Test - @DisplayName("Should capture and calculate GC statistics") - void shouldCaptureAndCalculateGCStatistics() { - // Test GC utility functionality - GCTestUtil.GCStatistics beforeStats = GCTestUtil.captureInitialStats(); - assertNotNull(beforeStats); - assertTrue(beforeStats.collections >= 0); - assertTrue(beforeStats.time >= 0); + @Test + @DisplayName("Should capture and calculate GC statistics") + void shouldCaptureAndCalculateGCStatistics() { + // Test GC utility functionality + GCTestUtil.GCStatistics beforeStats = GCTestUtil.captureInitialStats(); + assertNotNull(beforeStats); + assertTrue(beforeStats.collections >= 0); + assertTrue(beforeStats.time >= 0); - // Create some memory pressure - GCTestUtil.allocateMemory(10); // 10MB + // Create some memory pressure + GCTestUtil.allocateMemory(10); // 10MB - GCTestUtil.GCStatistics afterStats = GCTestUtil.calculateDelta(beforeStats); - assertNotNull(afterStats); - assertTrue(afterStats.collections >= 0); - assertTrue(afterStats.time >= 0); - } + GCTestUtil.GCStatistics afterStats = GCTestUtil.calculateDelta(beforeStats); + assertNotNull(afterStats); + assertTrue(afterStats.collections >= 0); + assertTrue(afterStats.time >= 0); + } - @Test - @DisplayName("Should measure operation time correctly") - void shouldMeasureOperationTimeCorrectly() { - long startTime = System.nanoTime(); + @Test + @DisplayName("Should measure operation time correctly") + void shouldMeasureOperationTimeCorrectly() { + long startTime = System.nanoTime(); - // Simulate some work - try { - Thread.sleep(10); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + // Simulate some work + try { + Thread.sleep(10); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } - long pauseTime = - GCTestUtil.measurePauseTime( - () -> { - // Simulate GC pause - try { + long pauseTime = GCTestUtil.measurePauseTime(() -> { + // Simulate GC pause + try { Thread.sleep(5); - } catch (InterruptedException e) { + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - } - }); + } + }); - assertTrue(pauseTime >= 0, "Pause time should be non-negative"); - // Note: This might not measure actual GC pause time in all cases, but tests the utility - } + assertTrue(pauseTime >= 0, "Pause time should be non-negative"); + // Note: This might not measure actual GC pause time in all cases, but tests the utility + } } diff --git a/src/test/java/fish/payara/trader/aeron/MarketDataFragmentHandlerTest.java b/src/test/java/fish/payara/trader/aeron/MarketDataFragmentHandlerTest.java index 90aa3a3..192190a 100644 --- a/src/test/java/fish/payara/trader/aeron/MarketDataFragmentHandlerTest.java +++ b/src/test/java/fish/payara/trader/aeron/MarketDataFragmentHandlerTest.java @@ -18,164 +18,166 @@ @ExtendWith(MockitoExtension.class) class MarketDataFragmentHandlerTest { - private MarketDataFragmentHandler handler; + private MarketDataFragmentHandler handler; - @Mock private MarketDataBroadcaster broadcaster; + @Mock + private MarketDataBroadcaster broadcaster; - @Mock private Header header; + @Mock + private Header header; - @BeforeEach - void setUp() { - handler = new MarketDataFragmentHandler(); - handler.broadcaster = broadcaster; - } - - @Test - void testProcessTradeMessage() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - TradeEncoder tradeEncoder = new TradeEncoder(); - - // Send 50 messages to ensure sampling triggers - for (int i = 0; i < 50; i++) { - tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); - tradeEncoder.timestamp(System.currentTimeMillis()); - tradeEncoder.symbol("AAPL"); - tradeEncoder.price(15000); - tradeEncoder.quantity(100); - - int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); - handler.onFragment(buffer, 0, encodedLength, header); + @BeforeEach + void setUp() { + handler = new MarketDataFragmentHandler(); + handler.broadcaster = broadcaster; } - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); - verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); - - String broadcastedMessage = messageCaptor.getValue(); - assertThat(broadcastedMessage).contains("\"type\":\"trade\""); - assertThat(broadcastedMessage).contains("\"symbol\":\"AAPL\""); - assertThat(broadcastedMessage).contains("\"price\":1.5"); - assertThat(broadcastedMessage).contains("\"quantity\":100"); - } - - @Test - void testProcessQuoteMessage() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - QuoteEncoder quoteEncoder = new QuoteEncoder(); - - // Send 50 messages to ensure sampling triggers - for (int i = 0; i < 50; i++) { - quoteEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); - quoteEncoder.timestamp(System.currentTimeMillis()); - quoteEncoder.symbol("MSFT"); - quoteEncoder.bidPrice(30000); - quoteEncoder.askPrice(30100); - quoteEncoder.bidSize(200); - quoteEncoder.askSize(150); - - int encodedLength = headerEncoder.encodedLength() + quoteEncoder.encodedLength(); - handler.onFragment(buffer, 0, encodedLength, header); + @Test + void testProcessTradeMessage() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + TradeEncoder tradeEncoder = new TradeEncoder(); + + // Send 50 messages to ensure sampling triggers + for (int i = 0; i < 50; i++) { + tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); + tradeEncoder.timestamp(System.currentTimeMillis()); + tradeEncoder.symbol("AAPL"); + tradeEncoder.price(15000); + tradeEncoder.quantity(100); + + int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); + } + + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); + + String broadcastedMessage = messageCaptor.getValue(); + assertThat(broadcastedMessage).contains("\"type\":\"trade\""); + assertThat(broadcastedMessage).contains("\"symbol\":\"AAPL\""); + assertThat(broadcastedMessage).contains("\"price\":1.5"); + assertThat(broadcastedMessage).contains("\"quantity\":100"); } - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); - verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); + @Test + void testProcessQuoteMessage() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + QuoteEncoder quoteEncoder = new QuoteEncoder(); + + // Send 50 messages to ensure sampling triggers + for (int i = 0; i < 50; i++) { + quoteEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); + quoteEncoder.timestamp(System.currentTimeMillis()); + quoteEncoder.symbol("MSFT"); + quoteEncoder.bidPrice(30000); + quoteEncoder.askPrice(30100); + quoteEncoder.bidSize(200); + quoteEncoder.askSize(150); + + int encodedLength = headerEncoder.encodedLength() + quoteEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); + } + + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); + + String broadcastedMessage = messageCaptor.getValue(); + assertThat(broadcastedMessage).contains("\"type\":\"quote\""); + assertThat(broadcastedMessage).contains("\"symbol\":\"MSFT\""); + assertThat(broadcastedMessage).contains("\"bid\":{\"price\":3.0"); + assertThat(broadcastedMessage).contains("\"ask\":{\"price\":3.01"); + } - String broadcastedMessage = messageCaptor.getValue(); - assertThat(broadcastedMessage).contains("\"type\":\"quote\""); - assertThat(broadcastedMessage).contains("\"symbol\":\"MSFT\""); - assertThat(broadcastedMessage).contains("\"bid\":{\"price\":3.0"); - assertThat(broadcastedMessage).contains("\"ask\":{\"price\":3.01"); - } + @Test + void testProcessHeartbeatMessage() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - @Test - void testProcessHeartbeatMessage() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + HeartbeatEncoder heartbeatEncoder = new HeartbeatEncoder(); - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - HeartbeatEncoder heartbeatEncoder = new HeartbeatEncoder(); + heartbeatEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); + heartbeatEncoder.timestamp(System.currentTimeMillis()); - heartbeatEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); - heartbeatEncoder.timestamp(System.currentTimeMillis()); + int encodedLength = headerEncoder.encodedLength() + heartbeatEncoder.encodedLength(); - int encodedLength = headerEncoder.encodedLength() + heartbeatEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); - handler.onFragment(buffer, 0, encodedLength, header); + verify(broadcaster, never()).broadcast(any()); + } - verify(broadcaster, never()).broadcast(any()); - } + @Test + void testMessageSampling() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - @Test - void testMessageSampling() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + TradeEncoder tradeEncoder = new TradeEncoder(); - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - TradeEncoder tradeEncoder = new TradeEncoder(); + for (int i = 0; i < 100; i++) { + tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); + tradeEncoder.timestamp(System.currentTimeMillis()); + tradeEncoder.symbol("TEST"); + tradeEncoder.price(10000 + i); + tradeEncoder.quantity(100); - for (int i = 0; i < 100; i++) { - tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); - tradeEncoder.timestamp(System.currentTimeMillis()); - tradeEncoder.symbol("TEST"); - tradeEncoder.price(10000 + i); - tradeEncoder.quantity(100); + int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); + } - int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); - handler.onFragment(buffer, 0, encodedLength, header); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(broadcaster, times(2)).broadcast(messageCaptor.capture()); } - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); - verify(broadcaster, times(2)).broadcast(messageCaptor.capture()); - } + @Test + void testInvalidTemplateId() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - @Test - void testInvalidTemplateId() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + headerEncoder.wrap(buffer, 0); + headerEncoder.blockLength(0); + headerEncoder.templateId(9999); + headerEncoder.schemaId(1); + headerEncoder.version(0); - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - headerEncoder.wrap(buffer, 0); - headerEncoder.blockLength(0); - headerEncoder.templateId(9999); - headerEncoder.schemaId(1); - headerEncoder.version(0); + int encodedLength = headerEncoder.encodedLength(); - int encodedLength = headerEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); - handler.onFragment(buffer, 0, encodedLength, header); + verify(broadcaster, never()).broadcast(any()); + } - verify(broadcaster, never()).broadcast(any()); - } + @Test + void testPriceConversion() { + ByteBuffer byteBuffer = ByteBuffer.allocate(256); + UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); - @Test - void testPriceConversion() { - ByteBuffer byteBuffer = ByteBuffer.allocate(256); - UnsafeBuffer buffer = new UnsafeBuffer(byteBuffer); + MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); + TradeEncoder tradeEncoder = new TradeEncoder(); - MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder(); - TradeEncoder tradeEncoder = new TradeEncoder(); + // Send 50 messages to ensure sampling triggers + for (int i = 0; i < 50; i++) { + tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); + tradeEncoder.timestamp(System.currentTimeMillis()); + tradeEncoder.symbol("XYZ"); + tradeEncoder.price(123456); + tradeEncoder.quantity(1); - // Send 50 messages to ensure sampling triggers - for (int i = 0; i < 50; i++) { - tradeEncoder.wrapAndApplyHeader(buffer, 0, headerEncoder); - tradeEncoder.timestamp(System.currentTimeMillis()); - tradeEncoder.symbol("XYZ"); - tradeEncoder.price(123456); - tradeEncoder.quantity(1); + int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); + handler.onFragment(buffer, 0, encodedLength, header); + } - int encodedLength = headerEncoder.encodedLength() + tradeEncoder.encodedLength(); - handler.onFragment(buffer, 0, encodedLength, header); - } + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); - verify(broadcaster, atLeastOnce()).broadcast(messageCaptor.capture()); - - String broadcastedMessage = messageCaptor.getValue(); - assertThat(broadcastedMessage).contains("\"price\":12.3456"); - } + String broadcastedMessage = messageCaptor.getValue(); + assertThat(broadcastedMessage).contains("\"price\":12.3456"); + } } diff --git a/src/test/java/fish/payara/trader/concurrency/ConcurrencyConfigTest.java b/src/test/java/fish/payara/trader/concurrency/ConcurrencyConfigTest.java index 4fa300b..e07b89b 100644 --- a/src/test/java/fish/payara/trader/concurrency/ConcurrencyConfigTest.java +++ b/src/test/java/fish/payara/trader/concurrency/ConcurrencyConfigTest.java @@ -11,302 +11,249 @@ @DisplayName("ConcurrencyConfig Tests") class ConcurrencyConfigTest { - @Test - @DisplayName("Should have ApplicationScoped annotation") - void shouldHaveApplicationScopedAnnotation() { - // Act - ApplicationScoped annotation = ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); - - // Assert - assertNotNull(annotation, "ApplicationScoped annotation should be present"); - } - - @Test - @DisplayName("Should have ManagedExecutorDefinition annotation") - void shouldHaveManagedExecutorDefinitionAnnotation() { - // Act - ManagedExecutorDefinition annotation = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - - // Assert - assertNotNull(annotation, "ManagedExecutorDefinition annotation should be present"); - } - - @Test - @DisplayName("Should have correct executor definition properties") - void shouldHaveCorrectExecutorDefinitionProperties() { - // Act - ManagedExecutorDefinition annotation = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - - // Assert - assertNotNull(annotation, "Annotation should be present"); - - // Check executor name - assertEquals( - "java:module/concurrent/VirtualThreadExecutor", - annotation.name(), - "Executor name should match expected value"); - - // Check virtual threads enabled - assertTrue(annotation.virtual(), "Virtual threads should be enabled"); - - // Check qualifiers - assertEquals(1, annotation.qualifiers().length, "Should have exactly one qualifier"); - assertEquals( - VirtualThreadExecutor.class, - annotation.qualifiers()[0], - "Should use VirtualThreadExecutor qualifier"); - } - - @Test - @DisplayName("Should be a concrete class") - void shouldBeAConcreteClass() { - // Assert - assertFalse( - ConcurrencyConfig.class.isInterface(), "ConcurrencyConfig should be a concrete class"); - assertFalse( - java.lang.reflect.Modifier.isAbstract(ConcurrencyConfig.class.getModifiers()), - "ConcurrencyConfig should not be abstract"); - assertTrue( - ConcurrencyConfig.class.isSynthetic() == false, - "ConcurrencyConfig should not be synthetic"); - } - - @Test - @DisplayName("Should be in correct package") - void shouldBeInCorrectPackage() { - // Assert - assertEquals( - "fish.payara.trader.concurrency", - ConcurrencyConfig.class.getPackage().getName(), - "Should be in fish.payara.trader.concurrency package"); - } - - @Test - @DisplayName("Should have correct simple name") - void shouldHaveCorrectSimpleName() { - // Assert - assertEquals( - "ConcurrencyConfig", - ConcurrencyConfig.class.getSimpleName(), - "Should have correct simple name"); - } - - @Test - @DisplayName("Should have public default constructor") - void shouldHavePublicDefaultConstructor() { - // Act - java.lang.reflect.Constructor[] constructors = ConcurrencyConfig.class.getConstructors(); - - // Assert - assertTrue(constructors.length > 0, "Should have at least one constructor"); - - // Should have a public no-args constructor - boolean hasPublicNoArgsConstructor = false; - for (java.lang.reflect.Constructor constructor : constructors) { - if (constructor.getParameterCount() == 0 - && java.lang.reflect.Modifier.isPublic(constructor.getModifiers())) { - hasPublicNoArgsConstructor = true; - break; - } + @Test + @DisplayName("Should have ApplicationScoped annotation") + void shouldHaveApplicationScopedAnnotation() { + // Act + ApplicationScoped annotation = ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); + + // Assert + assertNotNull(annotation, "ApplicationScoped annotation should be present"); } - assertTrue(hasPublicNoArgsConstructor, "Should have a public no-args constructor"); - } - - @Test - @DisplayName("Should create instances successfully") - void shouldCreateInstancesSuccessfully() { - // Act & Assert - assertDoesNotThrow( - () -> { - ConcurrencyConfig config = new ConcurrencyConfig(); - assertNotNull(config, "Should create instance without throwing exception"); - }, - "Should be able to create instance"); - } - - @Test - @DisplayName("Should not implement any interfaces") - void shouldNotImplementAnyInterfaces() { - // Act - Class[] interfaces = ConcurrencyConfig.class.getInterfaces(); - - // Assert - assertEquals(0, interfaces.length, "Should not implement any interfaces"); - } - - @Test - @DisplayName("Should have correct inheritance hierarchy") - void shouldHaveCorrectInheritanceHierarchy() { - // Act - Class superClass = ConcurrencyConfig.class.getSuperclass(); - - // Assert - assertEquals(Object.class, superClass, "Should extend Object class directly"); - } - - @Test - @DisplayName("Should be annotated with proper lifecycle scope") - void shouldBeAnnotatedWithProperLifecycleScope() { - // Act - ApplicationScoped applicationScoped = - ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); - - // Assert - assertNotNull(applicationScoped, "Should have ApplicationScoped annotation"); - assertEquals( - "jakarta.enterprise.context.ApplicationScoped", - applicationScoped.annotationType().getName(), - "Should use Jakarta EE ApplicationScoped"); - } - - @Test - @DisplayName("Should configure virtual threads for executor") - void shouldConfigureVirtualThreadsForExecutor() { - // Act - ManagedExecutorDefinition annotation = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - - // Assert - assertNotNull(annotation, "Should have ManagedExecutorDefinition"); - assertTrue(annotation.virtual(), "Should enable virtual threads"); - assertEquals( - "java:module/concurrent/VirtualThreadExecutor", - annotation.name(), - "Should use specific jndi name for virtual thread executor"); - } - - @Test - @DisplayName("Should have VirtualThreadExecutor qualifier") - void shouldHaveVirtualThreadExecutorQualifier() { - // Act - ManagedExecutorDefinition annotation = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - - // Assert - assertNotNull(annotation.qualifiers(), "Qualifiers array should not be null"); - assertEquals(1, annotation.qualifiers().length, "Should have exactly one qualifier"); - assertEquals( - VirtualThreadExecutor.class, - annotation.qualifiers()[0], - "Should use VirtualThreadExecutor as qualifier"); - } - - @Test - @DisplayName("Should have correct JNDI name pattern") - void shouldHaveCorrectJNDINamePattern() { - // Act - ManagedExecutorDefinition annotation = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - String jndiName = annotation.name(); - - // Assert - assertNotNull(jndiName, "JNDI name should not be null"); - assertEquals( - "java:module/concurrent/VirtualThreadExecutor", - jndiName, - "JNDI name should follow expected pattern"); - assertTrue( - jndiName.startsWith("java:module/concurrent/"), - "JNDI name should start with expected prefix"); - assertTrue( - jndiName.endsWith("VirtualThreadExecutor"), "JNDI name should end with expected suffix"); - assertFalse(jndiName.trim().isEmpty(), "JNDI name should not be empty"); - } - - @Test - @DisplayName("Should have no declared fields") - void shouldHaveNoDeclaredFields() { - // Act - java.lang.reflect.Field[] fields = ConcurrencyConfig.class.getDeclaredFields(); - - // Assert - assertEquals(0, fields.length, "Should have no declared fields"); - } - - @Test - @DisplayName("Should have no declared methods") - void shouldHaveNoDeclaredMethods() { - // Act - java.lang.reflect.Method[] methods = ConcurrencyConfig.class.getDeclaredMethods(); - - // Assert - // Java compiler may add synthetic methods, so we check for user-declared methods - long userMethods = - java.util.Arrays.stream(methods).filter(method -> !method.isSynthetic()).count(); - assertEquals(0, userMethods, "Should have no user-declared methods"); - } - - @Test - @DisplayName("Should have exactly two annotations") - void shouldHaveExactlyTwoAnnotations() { - // Act - java.lang.annotation.Annotation[] annotations = ConcurrencyConfig.class.getAnnotations(); - - // Assert - assertEquals(2, annotations.length, "Should have exactly two annotations"); - - // Verify annotation types - boolean hasApplicationScoped = false; - boolean hasManagedExecutorDefinition = false; - - for (java.lang.annotation.Annotation annotation : annotations) { - if (annotation instanceof ApplicationScoped) { - hasApplicationScoped = true; - } else if (annotation instanceof ManagedExecutorDefinition) { - hasManagedExecutorDefinition = true; - } + @Test + @DisplayName("Should have ManagedExecutorDefinition annotation") + void shouldHaveManagedExecutorDefinitionAnnotation() { + // Act + ManagedExecutorDefinition annotation = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + + // Assert + assertNotNull(annotation, "ManagedExecutorDefinition annotation should be present"); + } + + @Test + @DisplayName("Should have correct executor definition properties") + void shouldHaveCorrectExecutorDefinitionProperties() { + // Act + ManagedExecutorDefinition annotation = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + + // Assert + assertNotNull(annotation, "Annotation should be present"); + + // Check executor name + assertEquals("java:module/concurrent/VirtualThreadExecutor", annotation.name(), "Executor name should match expected value"); + + // Check virtual threads enabled + assertTrue(annotation.virtual(), "Virtual threads should be enabled"); + + // Check qualifiers + assertEquals(1, annotation.qualifiers().length, "Should have exactly one qualifier"); + assertEquals(VirtualThreadExecutor.class, annotation.qualifiers()[0], "Should use VirtualThreadExecutor qualifier"); + } + + @Test + @DisplayName("Should be a concrete class") + void shouldBeAConcreteClass() { + // Assert + assertFalse(ConcurrencyConfig.class.isInterface(), "ConcurrencyConfig should be a concrete class"); + assertFalse(java.lang.reflect.Modifier.isAbstract(ConcurrencyConfig.class.getModifiers()), "ConcurrencyConfig should not be abstract"); + assertTrue(ConcurrencyConfig.class.isSynthetic() == false, "ConcurrencyConfig should not be synthetic"); + } + + @Test + @DisplayName("Should be in correct package") + void shouldBeInCorrectPackage() { + // Assert + assertEquals("fish.payara.trader.concurrency", ConcurrencyConfig.class.getPackage().getName(), "Should be in fish.payara.trader.concurrency package"); + } + + @Test + @DisplayName("Should have correct simple name") + void shouldHaveCorrectSimpleName() { + // Assert + assertEquals("ConcurrencyConfig", ConcurrencyConfig.class.getSimpleName(), "Should have correct simple name"); + } + + @Test + @DisplayName("Should have public default constructor") + void shouldHavePublicDefaultConstructor() { + // Act + java.lang.reflect.Constructor[] constructors = ConcurrencyConfig.class.getConstructors(); + + // Assert + assertTrue(constructors.length > 0, "Should have at least one constructor"); + + // Should have a public no-args constructor + boolean hasPublicNoArgsConstructor = false; + for (java.lang.reflect.Constructor constructor : constructors) { + if (constructor.getParameterCount() == 0 && java.lang.reflect.Modifier.isPublic(constructor.getModifiers())) { + hasPublicNoArgsConstructor = true; + break; + } + } + + assertTrue(hasPublicNoArgsConstructor, "Should have a public no-args constructor"); + } + + @Test + @DisplayName("Should create instances successfully") + void shouldCreateInstancesSuccessfully() { + // Act & Assert + assertDoesNotThrow(() -> { + ConcurrencyConfig config = new ConcurrencyConfig(); + assertNotNull(config, "Should create instance without throwing exception"); + }, "Should be able to create instance"); + } + + @Test + @DisplayName("Should not implement any interfaces") + void shouldNotImplementAnyInterfaces() { + // Act + Class[] interfaces = ConcurrencyConfig.class.getInterfaces(); + + // Assert + assertEquals(0, interfaces.length, "Should not implement any interfaces"); + } + + @Test + @DisplayName("Should have correct inheritance hierarchy") + void shouldHaveCorrectInheritanceHierarchy() { + // Act + Class superClass = ConcurrencyConfig.class.getSuperclass(); + + // Assert + assertEquals(Object.class, superClass, "Should extend Object class directly"); + } + + @Test + @DisplayName("Should be annotated with proper lifecycle scope") + void shouldBeAnnotatedWithProperLifecycleScope() { + // Act + ApplicationScoped applicationScoped = ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); + + // Assert + assertNotNull(applicationScoped, "Should have ApplicationScoped annotation"); + assertEquals("jakarta.enterprise.context.ApplicationScoped", applicationScoped.annotationType().getName(), "Should use Jakarta EE ApplicationScoped"); + } + + @Test + @DisplayName("Should configure virtual threads for executor") + void shouldConfigureVirtualThreadsForExecutor() { + // Act + ManagedExecutorDefinition annotation = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + + // Assert + assertNotNull(annotation, "Should have ManagedExecutorDefinition"); + assertTrue(annotation.virtual(), "Should enable virtual threads"); + assertEquals("java:module/concurrent/VirtualThreadExecutor", annotation.name(), "Should use specific jndi name for virtual thread executor"); + } + + @Test + @DisplayName("Should have VirtualThreadExecutor qualifier") + void shouldHaveVirtualThreadExecutorQualifier() { + // Act + ManagedExecutorDefinition annotation = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + + // Assert + assertNotNull(annotation.qualifiers(), "Qualifiers array should not be null"); + assertEquals(1, annotation.qualifiers().length, "Should have exactly one qualifier"); + assertEquals(VirtualThreadExecutor.class, annotation.qualifiers()[0], "Should use VirtualThreadExecutor as qualifier"); } - assertTrue(hasApplicationScoped, "Should have ApplicationScoped annotation"); - assertTrue(hasManagedExecutorDefinition, "Should have ManagedExecutorDefinition annotation"); - } - - @Test - @DisplayName("Should be suitable for CDI bean registration") - void shouldBeSuitableForCDIBeanRegistration() { - // Act & Assert - This test verifies that the class has the right properties - // for CDI bean registration - - // Should have ApplicationScoped annotation - ApplicationScoped applicationScoped = - ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); - assertNotNull(applicationScoped, "Should have ApplicationScoped for CDI"); - - // Should have ManagedExecutorDefinition for executor configuration - ManagedExecutorDefinition managedExecutorDefinition = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - assertNotNull(managedExecutorDefinition, "Should have ManagedExecutorDefinition for CDI"); - - // Should be a concrete class with public constructor - assertDoesNotThrow( - () -> { - new ConcurrencyConfig(); - }, - "Should be instantiable by CDI"); - } - - @Test - @DisplayName("Should be properly configured for virtual threads") - void shouldBeProperlyConfiguredForVirtualThreads() { - // Act - ManagedExecutorDefinition definition = - ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); - - // Assert - assertTrue(definition.virtual(), "Should enable virtual threads"); - assertEquals( - "java:module/concurrent/VirtualThreadExecutor", - definition.name(), - "Should have correct JNDI name for virtual threads"); - - // Verify it uses VirtualThreadExecutor qualifier - assertEquals(1, definition.qualifiers().length); - assertEquals( - VirtualThreadExecutor.class, - definition.qualifiers()[0], - "Should use VirtualThreadExecutor qualifier"); - } + @Test + @DisplayName("Should have correct JNDI name pattern") + void shouldHaveCorrectJNDINamePattern() { + // Act + ManagedExecutorDefinition annotation = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + String jndiName = annotation.name(); + + // Assert + assertNotNull(jndiName, "JNDI name should not be null"); + assertEquals("java:module/concurrent/VirtualThreadExecutor", jndiName, "JNDI name should follow expected pattern"); + assertTrue(jndiName.startsWith("java:module/concurrent/"), "JNDI name should start with expected prefix"); + assertTrue(jndiName.endsWith("VirtualThreadExecutor"), "JNDI name should end with expected suffix"); + assertFalse(jndiName.trim().isEmpty(), "JNDI name should not be empty"); + } + + @Test + @DisplayName("Should have no declared fields") + void shouldHaveNoDeclaredFields() { + // Act + java.lang.reflect.Field[] fields = ConcurrencyConfig.class.getDeclaredFields(); + + // Assert + assertEquals(0, fields.length, "Should have no declared fields"); + } + + @Test + @DisplayName("Should have no declared methods") + void shouldHaveNoDeclaredMethods() { + // Act + java.lang.reflect.Method[] methods = ConcurrencyConfig.class.getDeclaredMethods(); + + // Assert + // Java compiler may add synthetic methods, so we check for user-declared methods + long userMethods = java.util.Arrays.stream(methods).filter(method -> !method.isSynthetic()).count(); + assertEquals(0, userMethods, "Should have no user-declared methods"); + } + + @Test + @DisplayName("Should have exactly two annotations") + void shouldHaveExactlyTwoAnnotations() { + // Act + java.lang.annotation.Annotation[] annotations = ConcurrencyConfig.class.getAnnotations(); + + // Assert + assertEquals(2, annotations.length, "Should have exactly two annotations"); + + // Verify annotation types + boolean hasApplicationScoped = false; + boolean hasManagedExecutorDefinition = false; + + for (java.lang.annotation.Annotation annotation : annotations) { + if (annotation instanceof ApplicationScoped) { + hasApplicationScoped = true; + } else if (annotation instanceof ManagedExecutorDefinition) { + hasManagedExecutorDefinition = true; + } + } + + assertTrue(hasApplicationScoped, "Should have ApplicationScoped annotation"); + assertTrue(hasManagedExecutorDefinition, "Should have ManagedExecutorDefinition annotation"); + } + + @Test + @DisplayName("Should be suitable for CDI bean registration") + void shouldBeSuitableForCDIBeanRegistration() { + // Act & Assert - This test verifies that the class has the right properties + // for CDI bean registration + + // Should have ApplicationScoped annotation + ApplicationScoped applicationScoped = ConcurrencyConfig.class.getAnnotation(ApplicationScoped.class); + assertNotNull(applicationScoped, "Should have ApplicationScoped for CDI"); + + // Should have ManagedExecutorDefinition for executor configuration + ManagedExecutorDefinition managedExecutorDefinition = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + assertNotNull(managedExecutorDefinition, "Should have ManagedExecutorDefinition for CDI"); + + // Should be a concrete class with public constructor + assertDoesNotThrow(() -> { + new ConcurrencyConfig(); + }, "Should be instantiable by CDI"); + } + + @Test + @DisplayName("Should be properly configured for virtual threads") + void shouldBeProperlyConfiguredForVirtualThreads() { + // Act + ManagedExecutorDefinition definition = ConcurrencyConfig.class.getAnnotation(ManagedExecutorDefinition.class); + + // Assert + assertTrue(definition.virtual(), "Should enable virtual threads"); + assertEquals("java:module/concurrent/VirtualThreadExecutor", definition.name(), "Should have correct JNDI name for virtual threads"); + + // Verify it uses VirtualThreadExecutor qualifier + assertEquals(1, definition.qualifiers().length); + assertEquals(VirtualThreadExecutor.class, definition.qualifiers()[0], "Should use VirtualThreadExecutor qualifier"); + } } diff --git a/src/test/java/fish/payara/trader/concurrency/VirtualThreadExecutorTest.java b/src/test/java/fish/payara/trader/concurrency/VirtualThreadExecutorTest.java index 0e4ce7f..768c881 100644 --- a/src/test/java/fish/payara/trader/concurrency/VirtualThreadExecutorTest.java +++ b/src/test/java/fish/payara/trader/concurrency/VirtualThreadExecutorTest.java @@ -14,194 +14,183 @@ @DisplayName("VirtualThreadExecutor Tests") class VirtualThreadExecutorTest { - @Test - @DisplayName("Should have correct annotation properties") - void shouldHaveCorrectAnnotationProperties() { - // Act - an annotation cannot annotate itself, so we test its properties instead - Class annotationType = VirtualThreadExecutor.class; - - // Assert - assertTrue(annotationType.isAnnotation(), "VirtualThreadExecutor should be an annotation type"); - assertNotNull(annotationType, "VirtualThreadExecutor class should be present"); - } - - @Test - @DisplayName("Should have Qualifier annotation") - void shouldHaveQualifierAnnotation() { - // Act - Qualifier qualifier = VirtualThreadExecutor.class.getAnnotation(Qualifier.class); - - // Assert - assertNotNull(qualifier, "VirtualThreadExecutor should have Qualifier annotation"); - } - - @Test - @DisplayName("Should have correct target types") - void shouldHaveCorrectTargetTypes() { - // Act - Target target = VirtualThreadExecutor.class.getAnnotation(Target.class); - - // Assert - assertNotNull(target, "Target annotation should be present"); - ElementType[] elementTypes = target.value(); - - assertTrue(containsTarget(elementTypes, ElementType.METHOD), "Should target METHOD"); - assertTrue(containsTarget(elementTypes, ElementType.FIELD), "Should target FIELD"); - assertTrue(containsTarget(elementTypes, ElementType.PARAMETER), "Should target PARAMETER"); - assertTrue(containsTarget(elementTypes, ElementType.TYPE), "Should target TYPE"); - } - - @Test - @DisplayName("Should have correct retention policy") - void shouldHaveCorrectRetentionPolicy() { - // Act - Retention retention = VirtualThreadExecutor.class.getAnnotation(Retention.class); - - // Assert - assertNotNull(retention, "Retention annotation should be present"); - assertEquals( - RetentionPolicy.RUNTIME, retention.value(), "Should have RUNTIME retention policy"); - } - - @Test - @DisplayName("Should be an interface") - void shouldBeAnInterface() { - // Assert - assertTrue( - VirtualThreadExecutor.class.isInterface(), "VirtualThreadExecutor should be an interface"); - } - - @Test - @DisplayName("Should be in correct package") - void shouldBeInCorrectPackage() { - // Assert - assertEquals( - "fish.payara.trader.concurrency", - VirtualThreadExecutor.class.getPackage().getName(), - "Should be in fish.payara.trader.concurrency package"); - } - - @Test - @DisplayName("Should have correct simple name") - void shouldHaveCorrectSimpleName() { - // Assert - assertEquals( - "VirtualThreadExecutor", - VirtualThreadExecutor.class.getSimpleName(), - "Should have correct simple name"); - } - - @Test - @DisplayName("Should be an annotation interface") - void shouldBeAnAnnotationInterface() { - // Act - boolean isAnnotation = VirtualThreadExecutor.class.isAnnotation(); - - // Assert - assertTrue(isAnnotation, "VirtualThreadExecutor should be an annotation interface"); - } - - @Test - @DisplayName("Should have no declared methods") - void shouldHaveNoDeclaredMethods() { - // Act - java.lang.reflect.Method[] methods = VirtualThreadExecutor.class.getDeclaredMethods(); - - // Assert - assertEquals(0, methods.length, "Should have no declared methods"); - } - - @Test - @DisplayName("Should have no declared fields") - void shouldHaveNoDeclaredFields() { - // Act - java.lang.reflect.Field[] fields = VirtualThreadExecutor.class.getDeclaredFields(); - - // Assert - assertEquals(0, fields.length, "Should have no declared fields"); - } - - @Test - @DisplayName("Should have no declared constructors") - void shouldHaveNoDeclaredConstructors() { - // Act - java.lang.reflect.Constructor[] constructors = - VirtualThreadExecutor.class.getDeclaredConstructors(); - - // Assert - assertEquals(0, constructors.length, "Should have no declared constructors"); - } - - @Test - @DisplayName("Should have no declared annotations except standard ones") - void shouldHaveNoDeclaredAnnotationsExceptStandardOnes() { - // Act - java.lang.annotation.Annotation[] annotations = - VirtualThreadExecutor.class.getDeclaredAnnotations(); - - // Assert - // Should have exactly 3 annotations: @Target, @Retention, @Qualifier - assertEquals(3, annotations.length, "Should have exactly 3 declared annotations"); - - // Verify the types of annotations - boolean hasTarget = false; - boolean hasRetention = false; - boolean hasQualifier = false; - - for (java.lang.annotation.Annotation annotation : annotations) { - if (annotation instanceof Target) { - hasTarget = true; - } else if (annotation instanceof Retention) { - hasRetention = true; - } else if (annotation instanceof Qualifier) { - hasQualifier = true; - } + @Test + @DisplayName("Should have correct annotation properties") + void shouldHaveCorrectAnnotationProperties() { + // Act - an annotation cannot annotate itself, so we test its properties instead + Class annotationType = VirtualThreadExecutor.class; + + // Assert + assertTrue(annotationType.isAnnotation(), "VirtualThreadExecutor should be an annotation type"); + assertNotNull(annotationType, "VirtualThreadExecutor class should be present"); } - assertTrue(hasTarget, "Should have @Target annotation"); - assertTrue(hasRetention, "Should have @Retention annotation"); - assertTrue(hasQualifier, "Should have @Qualifier annotation"); - } - - @Test - @DisplayName("Should be suitable for dependency injection") - void shouldBeSuitableForDependencyInjection() { - // Act & Assert - This test verifies that the annotation has the right properties - // for use in CDI/dependency injection frameworks - - // Should be a qualifier annotation (jakarta.inject.Qualifier) - Qualifier qualifier = VirtualThreadExecutor.class.getAnnotation(Qualifier.class); - assertNotNull(qualifier, "Should be a CDI Qualifier annotation"); - - // Should be retained at runtime for injection - Retention retention = VirtualThreadExecutor.class.getAnnotation(Retention.class); - assertEquals( - RetentionPolicy.RUNTIME, retention.value(), "Should be retained at runtime for injection"); - } - - @Test - @DisplayName("Should have descriptive documentation") - void shouldHaveDescriptiveDocumentation() { - // Act - String className = VirtualThreadExecutor.class.getSimpleName(); - Package pkg = VirtualThreadExecutor.class.getPackage(); - - // Assert - assertEquals("VirtualThreadExecutor", className, "Should have descriptive name"); - assertEquals( - "fish.payara.trader.concurrency", pkg.getName(), "Should be in meaningful package"); - - // Note: We can't easily test javadoc content without additional libraries, - // but we can verify that the class is documented by its existence and naming - } - - /** Helper method to check if target array contains specific element type */ - private boolean containsTarget(ElementType[] targets, ElementType targetType) { - for (ElementType target : targets) { - if (target == targetType) { - return true; - } + @Test + @DisplayName("Should have Qualifier annotation") + void shouldHaveQualifierAnnotation() { + // Act + Qualifier qualifier = VirtualThreadExecutor.class.getAnnotation(Qualifier.class); + + // Assert + assertNotNull(qualifier, "VirtualThreadExecutor should have Qualifier annotation"); + } + + @Test + @DisplayName("Should have correct target types") + void shouldHaveCorrectTargetTypes() { + // Act + Target target = VirtualThreadExecutor.class.getAnnotation(Target.class); + + // Assert + assertNotNull(target, "Target annotation should be present"); + ElementType[] elementTypes = target.value(); + + assertTrue(containsTarget(elementTypes, ElementType.METHOD), "Should target METHOD"); + assertTrue(containsTarget(elementTypes, ElementType.FIELD), "Should target FIELD"); + assertTrue(containsTarget(elementTypes, ElementType.PARAMETER), "Should target PARAMETER"); + assertTrue(containsTarget(elementTypes, ElementType.TYPE), "Should target TYPE"); + } + + @Test + @DisplayName("Should have correct retention policy") + void shouldHaveCorrectRetentionPolicy() { + // Act + Retention retention = VirtualThreadExecutor.class.getAnnotation(Retention.class); + + // Assert + assertNotNull(retention, "Retention annotation should be present"); + assertEquals(RetentionPolicy.RUNTIME, retention.value(), "Should have RUNTIME retention policy"); + } + + @Test + @DisplayName("Should be an interface") + void shouldBeAnInterface() { + // Assert + assertTrue(VirtualThreadExecutor.class.isInterface(), "VirtualThreadExecutor should be an interface"); + } + + @Test + @DisplayName("Should be in correct package") + void shouldBeInCorrectPackage() { + // Assert + assertEquals("fish.payara.trader.concurrency", VirtualThreadExecutor.class.getPackage().getName(), + "Should be in fish.payara.trader.concurrency package"); + } + + @Test + @DisplayName("Should have correct simple name") + void shouldHaveCorrectSimpleName() { + // Assert + assertEquals("VirtualThreadExecutor", VirtualThreadExecutor.class.getSimpleName(), "Should have correct simple name"); + } + + @Test + @DisplayName("Should be an annotation interface") + void shouldBeAnAnnotationInterface() { + // Act + boolean isAnnotation = VirtualThreadExecutor.class.isAnnotation(); + + // Assert + assertTrue(isAnnotation, "VirtualThreadExecutor should be an annotation interface"); + } + + @Test + @DisplayName("Should have no declared methods") + void shouldHaveNoDeclaredMethods() { + // Act + java.lang.reflect.Method[] methods = VirtualThreadExecutor.class.getDeclaredMethods(); + + // Assert + assertEquals(0, methods.length, "Should have no declared methods"); + } + + @Test + @DisplayName("Should have no declared fields") + void shouldHaveNoDeclaredFields() { + // Act + java.lang.reflect.Field[] fields = VirtualThreadExecutor.class.getDeclaredFields(); + + // Assert + assertEquals(0, fields.length, "Should have no declared fields"); + } + + @Test + @DisplayName("Should have no declared constructors") + void shouldHaveNoDeclaredConstructors() { + // Act + java.lang.reflect.Constructor[] constructors = VirtualThreadExecutor.class.getDeclaredConstructors(); + + // Assert + assertEquals(0, constructors.length, "Should have no declared constructors"); + } + + @Test + @DisplayName("Should have no declared annotations except standard ones") + void shouldHaveNoDeclaredAnnotationsExceptStandardOnes() { + // Act + java.lang.annotation.Annotation[] annotations = VirtualThreadExecutor.class.getDeclaredAnnotations(); + + // Assert + // Should have exactly 3 annotations: @Target, @Retention, @Qualifier + assertEquals(3, annotations.length, "Should have exactly 3 declared annotations"); + + // Verify the types of annotations + boolean hasTarget = false; + boolean hasRetention = false; + boolean hasQualifier = false; + + for (java.lang.annotation.Annotation annotation : annotations) { + if (annotation instanceof Target) { + hasTarget = true; + } else if (annotation instanceof Retention) { + hasRetention = true; + } else if (annotation instanceof Qualifier) { + hasQualifier = true; + } + } + + assertTrue(hasTarget, "Should have @Target annotation"); + assertTrue(hasRetention, "Should have @Retention annotation"); + assertTrue(hasQualifier, "Should have @Qualifier annotation"); + } + + @Test + @DisplayName("Should be suitable for dependency injection") + void shouldBeSuitableForDependencyInjection() { + // Act & Assert - This test verifies that the annotation has the right properties + // for use in CDI/dependency injection frameworks + + // Should be a qualifier annotation (jakarta.inject.Qualifier) + Qualifier qualifier = VirtualThreadExecutor.class.getAnnotation(Qualifier.class); + assertNotNull(qualifier, "Should be a CDI Qualifier annotation"); + + // Should be retained at runtime for injection + Retention retention = VirtualThreadExecutor.class.getAnnotation(Retention.class); + assertEquals(RetentionPolicy.RUNTIME, retention.value(), "Should be retained at runtime for injection"); + } + + @Test + @DisplayName("Should have descriptive documentation") + void shouldHaveDescriptiveDocumentation() { + // Act + String className = VirtualThreadExecutor.class.getSimpleName(); + Package pkg = VirtualThreadExecutor.class.getPackage(); + + // Assert + assertEquals("VirtualThreadExecutor", className, "Should have descriptive name"); + assertEquals("fish.payara.trader.concurrency", pkg.getName(), "Should be in meaningful package"); + + // Note: We can't easily test javadoc content without additional libraries, + // but we can verify that the class is documented by its existence and naming + } + + /** Helper method to check if target array contains specific element type */ + private boolean containsTarget(ElementType[] targets, ElementType targetType) { + for (ElementType target : targets) { + if (target == targetType) { + return true; + } + } + return false; } - return false; - } } diff --git a/src/test/java/fish/payara/trader/gc/GCStatsServiceTest.java b/src/test/java/fish/payara/trader/gc/GCStatsServiceTest.java index 68ad242..3302047 100644 --- a/src/test/java/fish/payara/trader/gc/GCStatsServiceTest.java +++ b/src/test/java/fish/payara/trader/gc/GCStatsServiceTest.java @@ -19,123 +19,103 @@ @DisplayName("GCStatsService Tests") class GCStatsServiceTest { - private GCStatsService gcStatsService; - - @BeforeEach - void setUp() { - gcStatsService = new GCStatsService(); - } - - @Test - @DisplayName("Should handle GC notification and record pause") - void shouldHandleGCNotificationAndRecordPause() { - Notification notification = - new Notification( - GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); - CompositeData compositeData = mock(CompositeData.class); - notification.setUserData(compositeData); - - GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); - GcInfo gcInfo = mock(GcInfo.class); - - when(info.getGcName()).thenReturn("G1 Young Generation"); - when(info.getGcAction()).thenReturn("end of minor GC"); - when(info.getGcCause()).thenReturn("System.gc()"); - when(info.getGcInfo()).thenReturn(gcInfo); - when(gcInfo.getDuration()).thenReturn(50L); - - try (MockedStatic mockedStatic = - mockStatic(GarbageCollectionNotificationInfo.class)) { - mockedStatic - .when(() -> GarbageCollectionNotificationInfo.from(compositeData)) - .thenReturn(info); - - gcStatsService.handleNotification(notification, null); - } + private GCStatsService gcStatsService; - List stats = gcStatsService.collectGCStats(); - // We expect at least the G1 Young Generation to be present if the JVM is running G1 - // But since collectGCStats calls ManagementFactory.getGarbageCollectorMXBeans(), - // it depends on the actual JVM. - // However, we can verify the pauseHistory internal state by calling collectGCStats - // and looking for the one we just injected. - - GCStats g1Stats = - stats.stream() - .filter(s -> s.getGcName().equals("G1 Young Generation")) - .findFirst() - .orElse(null); - - if (g1Stats != null) { - assertThat(g1Stats.getLastPauseDuration()).isEqualTo(50L); - assertThat(g1Stats.getRecentPauses()).contains(50L); - } - } - - @Test - @DisplayName("Should filter GPGC concurrent cycle notifications") - void shouldFilterGPGCConcurrentCycleNotifications() { - Notification notification = - new Notification( - GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); - CompositeData compositeData = mock(CompositeData.class); - notification.setUserData(compositeData); - - GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); - GcInfo gcInfo = mock(GcInfo.class); - - when(info.getGcName()).thenReturn("GPGC"); // This should be filtered - when(info.getGcInfo()).thenReturn(gcInfo); - when(gcInfo.getDuration()).thenReturn(500L); - - try (MockedStatic mockedStatic = - mockStatic(GarbageCollectionNotificationInfo.class)) { - mockedStatic - .when(() -> GarbageCollectionNotificationInfo.from(compositeData)) - .thenReturn(info); - - gcStatsService.handleNotification(notification, null); + @BeforeEach + void setUp() { + gcStatsService = new GCStatsService(); } - List stats = gcStatsService.collectGCStats(); - GCStats gpgcStats = - stats.stream().filter(s -> s.getGcName().equals("GPGC")).findFirst().orElse(null); - - // GPGC should be excluded from stats - assertThat(gpgcStats).isNull(); - } - - @Test - @DisplayName("Should reset statistics") - void shouldResetStatistics() { - Notification notification = - new Notification( - GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); - CompositeData compositeData = mock(CompositeData.class); - notification.setUserData(compositeData); - - GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); - GcInfo gcInfo = mock(GcInfo.class); - - when(info.getGcName()).thenReturn("Test GC"); - when(info.getGcInfo()).thenReturn(gcInfo); - when(gcInfo.getDuration()).thenReturn(100L); - - try (MockedStatic mockedStatic = - mockStatic(GarbageCollectionNotificationInfo.class)) { - mockedStatic - .when(() -> GarbageCollectionNotificationInfo.from(compositeData)) - .thenReturn(info); - gcStatsService.handleNotification(notification, null); + @Test + @DisplayName("Should handle GC notification and record pause") + void shouldHandleGCNotificationAndRecordPause() { + Notification notification = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); + CompositeData compositeData = mock(CompositeData.class); + notification.setUserData(compositeData); + + GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); + GcInfo gcInfo = mock(GcInfo.class); + + when(info.getGcName()).thenReturn("G1 Young Generation"); + when(info.getGcAction()).thenReturn("end of minor GC"); + when(info.getGcCause()).thenReturn("System.gc()"); + when(info.getGcInfo()).thenReturn(gcInfo); + when(gcInfo.getDuration()).thenReturn(50L); + + try (MockedStatic mockedStatic = mockStatic(GarbageCollectionNotificationInfo.class)) { + mockedStatic.when(() -> GarbageCollectionNotificationInfo.from(compositeData)).thenReturn(info); + + gcStatsService.handleNotification(notification, null); + } + + List stats = gcStatsService.collectGCStats(); + // We expect at least the G1 Young Generation to be present if the JVM is running G1 + // But since collectGCStats calls ManagementFactory.getGarbageCollectorMXBeans(), + // it depends on the actual JVM. + // However, we can verify the pauseHistory internal state by calling collectGCStats + // and looking for the one we just injected. + + GCStats g1Stats = stats.stream().filter(s -> s.getGcName().equals("G1 Young Generation")).findFirst().orElse(null); + + if (g1Stats != null) { + assertThat(g1Stats.getLastPauseDuration()).isEqualTo(50L); + assertThat(g1Stats.getRecentPauses()).contains(50L); + } } - gcStatsService.resetStats(); + @Test + @DisplayName("Should filter GPGC concurrent cycle notifications") + void shouldFilterGPGCConcurrentCycleNotifications() { + Notification notification = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); + CompositeData compositeData = mock(CompositeData.class); + notification.setUserData(compositeData); + + GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); + GcInfo gcInfo = mock(GcInfo.class); + + when(info.getGcName()).thenReturn("GPGC"); // This should be filtered + when(info.getGcInfo()).thenReturn(gcInfo); + when(gcInfo.getDuration()).thenReturn(500L); + + try (MockedStatic mockedStatic = mockStatic(GarbageCollectionNotificationInfo.class)) { + mockedStatic.when(() -> GarbageCollectionNotificationInfo.from(compositeData)).thenReturn(info); + + gcStatsService.handleNotification(notification, null); + } + + List stats = gcStatsService.collectGCStats(); + GCStats gpgcStats = stats.stream().filter(s -> s.getGcName().equals("GPGC")).findFirst().orElse(null); + + // GPGC should be excluded from stats + assertThat(gpgcStats).isNull(); + } - // After reset, even if the bean exists in JVM, the pause history should be gone - List stats = gcStatsService.collectGCStats(); - for (GCStats s : stats) { - assertThat(s.getRecentPauses()).isEmpty(); - assertThat(s.getLastPauseDuration()).isZero(); + @Test + @DisplayName("Should reset statistics") + void shouldResetStatistics() { + Notification notification = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, "test", 1L); + CompositeData compositeData = mock(CompositeData.class); + notification.setUserData(compositeData); + + GarbageCollectionNotificationInfo info = mock(GarbageCollectionNotificationInfo.class); + GcInfo gcInfo = mock(GcInfo.class); + + when(info.getGcName()).thenReturn("Test GC"); + when(info.getGcInfo()).thenReturn(gcInfo); + when(gcInfo.getDuration()).thenReturn(100L); + + try (MockedStatic mockedStatic = mockStatic(GarbageCollectionNotificationInfo.class)) { + mockedStatic.when(() -> GarbageCollectionNotificationInfo.from(compositeData)).thenReturn(info); + gcStatsService.handleNotification(notification, null); + } + + gcStatsService.resetStats(); + + // After reset, even if the bean exists in JVM, the pause history should be gone + List stats = gcStatsService.collectGCStats(); + for (GCStats s : stats) { + assertThat(s.getRecentPauses()).isEmpty(); + assertThat(s.getLastPauseDuration()).isZero(); + } } - } } diff --git a/src/test/java/fish/payara/trader/gc/GCStatsTest.java b/src/test/java/fish/payara/trader/gc/GCStatsTest.java index b22e594..50dc119 100644 --- a/src/test/java/fish/payara/trader/gc/GCStatsTest.java +++ b/src/test/java/fish/payara/trader/gc/GCStatsTest.java @@ -12,548 +12,514 @@ @DisplayName("GCStats Tests") class GCStatsTest { - @Nested - @DisplayName("Constructor and Basic Properties Tests") - class ConstructorAndBasicPropertiesTests { - - @Test - @DisplayName("Should create GCStats with default constructor") - void shouldCreateGCStatsWithDefaultConstructor() { - GCStats stats = new GCStats(); - - assertNotNull(stats, "GCStats should not be null"); - assertNull(stats.getGcName(), "GC name should be null by default"); - assertEquals(0L, stats.getCollectionCount(), "Collection count should default to 0"); - assertEquals(0L, stats.getCollectionTime(), "Collection time should default to 0"); - assertEquals(0L, stats.getLastPauseDuration(), "Last pause duration should default to 0"); - assertNull(stats.getRecentPauses(), "Recent pauses should be null by default"); - assertNull(stats.getPercentiles(), "Percentiles should be null by default"); - assertEquals(0L, stats.getTotalMemory(), "Total memory should default to 0"); - assertEquals(0L, stats.getUsedMemory(), "Used memory should default to 0"); - assertEquals(0L, stats.getFreeMemory(), "Free memory should default to 0"); + @Nested + @DisplayName("Constructor and Basic Properties Tests") + class ConstructorAndBasicPropertiesTests { + + @Test + @DisplayName("Should create GCStats with default constructor") + void shouldCreateGCStatsWithDefaultConstructor() { + GCStats stats = new GCStats(); + + assertNotNull(stats, "GCStats should not be null"); + assertNull(stats.getGcName(), "GC name should be null by default"); + assertEquals(0L, stats.getCollectionCount(), "Collection count should default to 0"); + assertEquals(0L, stats.getCollectionTime(), "Collection time should default to 0"); + assertEquals(0L, stats.getLastPauseDuration(), "Last pause duration should default to 0"); + assertNull(stats.getRecentPauses(), "Recent pauses should be null by default"); + assertNull(stats.getPercentiles(), "Percentiles should be null by default"); + assertEquals(0L, stats.getTotalMemory(), "Total memory should default to 0"); + assertEquals(0L, stats.getUsedMemory(), "Used memory should default to 0"); + assertEquals(0L, stats.getFreeMemory(), "Free memory should default to 0"); + } + } + + @Nested + @DisplayName("GC Name Tests") + class GCNameTests { + + @Test + @DisplayName("Should set and get GC name correctly") + void shouldSetAndGetGCNameCorrectly() { + GCStats stats = new GCStats(); + String gcName = "G1 Young Generation"; + + stats.setGcName(gcName); + assertEquals(gcName, stats.getGcName(), "GC name should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle null GC name") + void shouldHandleNullGCName() { + GCStats stats = new GCStats(); + + assertDoesNotThrow(() -> stats.setGcName(null), "Setting null GC name should not throw"); + assertNull(stats.getGcName(), "GC name should be null"); + } + + @Test + @DisplayName("Should handle empty GC name") + void shouldHandleEmptyGCName() { + GCStats stats = new GCStats(); + String emptyName = ""; + + stats.setGcName(emptyName); + assertEquals(emptyName, stats.getGcName(), "Empty GC name should be handled"); + } + + @Test + @DisplayName("Should handle special characters in GC name") + void shouldHandleSpecialCharactersInGCName() { + GCStats stats = new GCStats(); + String specialName = "G1/Young (Test) @#$%^&*()"; + + stats.setGcName(specialName); + assertEquals(specialName, stats.getGcName(), "Special characters should be preserved"); + } + } + + @Nested + @DisplayName("Collection Statistics Tests") + class CollectionStatisticsTests { + + @Test + @DisplayName("Should set and get collection count correctly") + void shouldSetAndGetCollectionCountCorrectly() { + GCStats stats = new GCStats(); + long collectionCount = 12345L; + + stats.setCollectionCount(collectionCount); + assertEquals(collectionCount, stats.getCollectionCount(), "Collection count should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle zero collection count") + void shouldHandleZeroCollectionCount() { + GCStats stats = new GCStats(); + + stats.setCollectionCount(0L); + assertEquals(0L, stats.getCollectionCount(), "Zero collection count should be handled"); + } + + @Test + @DisplayName("Should handle negative collection count") + void shouldHandleNegativeCollectionCount() { + GCStats stats = new GCStats(); + long negativeCount = -100L; + + stats.setCollectionCount(negativeCount); + assertEquals(negativeCount, stats.getCollectionCount(), "Negative collection count should be handled"); + } + + @Test + @DisplayName("Should handle very large collection count") + void shouldHandleVeryLargeCollectionCount() { + GCStats stats = new GCStats(); + long largeCount = Long.MAX_VALUE; + + stats.setCollectionCount(largeCount); + assertEquals(largeCount, stats.getCollectionCount(), "Very large collection count should be handled"); + } + + @Test + @DisplayName("Should set and get collection time correctly") + void shouldSetAndGetCollectionTimeCorrectly() { + GCStats stats = new GCStats(); + long collectionTime = 98765L; + + stats.setCollectionTime(collectionTime); + assertEquals(collectionTime, stats.getCollectionTime(), "Collection time should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle zero collection time") + void shouldHandleZeroCollectionTime() { + GCStats stats = new GCStats(); + + stats.setCollectionTime(0L); + assertEquals(0L, stats.getCollectionTime(), "Zero collection time should be handled"); + } + + @Test + @DisplayName("Should handle negative collection time") + void shouldHandleNegativeCollectionTime() { + GCStats stats = new GCStats(); + long negativeTime = -500L; + + stats.setCollectionTime(negativeTime); + assertEquals(negativeTime, stats.getCollectionTime(), "Negative collection time should be handled"); + } + } + + @Nested + @DisplayName("Pause Duration Tests") + class PauseDurationTests { + + @Test + @DisplayName("Should set and get last pause duration correctly") + void shouldSetAndGetLastPauseDurationCorrectly() { + GCStats stats = new GCStats(); + long pauseDuration = 150L; + + stats.setLastPauseDuration(pauseDuration); + assertEquals(pauseDuration, stats.getLastPauseDuration(), "Last pause duration should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle zero pause duration") + void shouldHandleZeroPauseDuration() { + GCStats stats = new GCStats(); + + stats.setLastPauseDuration(0L); + assertEquals(0L, stats.getLastPauseDuration(), "Zero pause duration should be handled"); + } + + @Test + @DisplayName("Should handle very long pause duration") + void shouldHandleVeryLongPauseDuration() { + GCStats stats = new GCStats(); + long longPause = 30000L; // 30 seconds + + stats.setLastPauseDuration(longPause); + assertEquals(longPause, stats.getLastPauseDuration(), "Very long pause duration should be handled"); + } + + @Test + @DisplayName("Should handle microsecond-level pause duration") + void shouldHandleMicrosecondLevelPauseDuration() { + GCStats stats = new GCStats(); + long microPause = 1L; // 1 millisecond (micro in practice) + + stats.setLastPauseDuration(microPause); + assertEquals(microPause, stats.getLastPauseDuration(), "Microsecond-level pause duration should be handled"); + } + } + + @Nested + @DisplayName("Recent Pauses Tests") + class RecentPausesTests { + + @Test + @DisplayName("Should set and get recent pauses list correctly") + void shouldSetAndGetRecentPausesListCorrectly() { + GCStats stats = new GCStats(); + List pauses = Arrays.asList(10L, 25L, 15L, 30L, 12L); + + stats.setRecentPauses(pauses); + assertEquals(pauses, stats.getRecentPauses(), "Recent pauses list should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle empty recent pauses list") + void shouldHandleEmptyRecentPausesList() { + GCStats stats = new GCStats(); + List emptyList = List.of(); + + stats.setRecentPauses(emptyList); + assertEquals(emptyList, stats.getRecentPauses(), "Empty recent pauses list should be handled"); + } + + @Test + @DisplayName("Should handle null recent pauses list") + void shouldHandleNullRecentPausesList() { + GCStats stats = new GCStats(); + + assertDoesNotThrow(() -> stats.setRecentPauses(null), "Setting null recent pauses should not throw"); + assertNull(stats.getRecentPauses(), "Recent pauses should be null"); + } + + @Test + @DisplayName("Should handle recent pauses with zero values") + void shouldHandleRecentPausesWithZeroValues() { + GCStats stats = new GCStats(); + List zeros = Arrays.asList(0L, 0L, 0L, 0L); + + stats.setRecentPauses(zeros); + assertEquals(zeros, stats.getRecentPauses(), "Zero pause values should be handled"); + } + + @Test + @DisplayName("Should handle recent pauses with mixed values") + void shouldHandleRecentPausesWithMixedValues() { + GCStats stats = new GCStats(); + List mixedValues = Arrays.asList(5L, 0L, 1000L, 1L, 500L); + + stats.setRecentPauses(mixedValues); + assertEquals(mixedValues, stats.getRecentPauses(), "Mixed pause values should be handled"); + } + } + + @Nested + @DisplayName("Percentiles Tests") + class PercentilesTests { + + @Test + @DisplayName("Should set and get percentiles correctly") + void shouldSetAndGetPercentilesCorrectly() { + GCStats stats = new GCStats(); + GCStats.PausePercentiles percentiles = new GCStats.PausePercentiles(10L, 25L, 50L, 100L, 200L); + + stats.setPercentiles(percentiles); + assertEquals(percentiles, stats.getPercentiles(), "Percentiles should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should handle null percentiles") + void shouldHandleNullPercentiles() { + GCStats stats = new GCStats(); + + assertDoesNotThrow(() -> stats.setPercentiles(null), "Setting null percentiles should not throw"); + assertNull(stats.getPercentiles(), "Percentiles should be null"); + } + + @Test + @DisplayName("Should handle all zero percentile values") + void shouldHandleAllZeroPercentileValues() { + GCStats stats = new GCStats(); + GCStats.PausePercentiles zeroPercentiles = new GCStats.PausePercentiles(0L, 0L, 0L, 0L, 0L); + + stats.setPercentiles(zeroPercentiles); + assertEquals(0L, stats.getPercentiles().getP50(), "P50 should be zero"); + assertEquals(0L, stats.getPercentiles().getP95(), "P95 should be zero"); + assertEquals(0L, stats.getPercentiles().getP99(), "P99 should be zero"); + assertEquals(0L, stats.getPercentiles().getP999(), "P999 should be zero"); + assertEquals(0L, stats.getPercentiles().getMax(), "Max should be zero"); + } + + @Test + @DisplayName("Should handle percentile with constructor") + void shouldHandlePercentileWithConstructor() { + long p50 = 15L, p95 = 50L, p99 = 120L, p999 = 300L, max = 500L; + GCStats.PausePercentiles percentiles = new GCStats.PausePercentiles(p50, p95, p99, p999, max); + + assertEquals(p50, percentiles.getP50(), "P50 should match constructor value"); + assertEquals(p95, percentiles.getP95(), "P95 should match constructor value"); + assertEquals(p99, percentiles.getP99(), "P99 should match constructor value"); + assertEquals(p999, percentiles.getP999(), "P999 should match constructor value"); + assertEquals(max, percentiles.getMax(), "Max should match constructor value"); + } + + @Test + @DisplayName("Should handle percentile setters and getters") + void shouldHandlePercentileSettersAndGetters() { + GCStats.PausePercentiles percentiles = new GCStats.PausePercentiles(); + + long p50 = 25L, p95 = 75L, p99 = 150L, p999 = 400L, max = 800L; + + percentiles.setP50(p50); + percentiles.setP95(p95); + percentiles.setP99(p99); + percentiles.setP999(p999); + percentiles.setMax(max); + + assertEquals(p50, percentiles.getP50(), "P50 should be set correctly"); + assertEquals(p95, percentiles.getP95(), "P95 should be set correctly"); + assertEquals(p99, percentiles.getP99(), "P99 should be set correctly"); + assertEquals(p999, percentiles.getP999(), "P999 should be set correctly"); + assertEquals(max, percentiles.getMax(), "Max should be set correctly"); + } + } + + @Nested + @DisplayName("Memory Statistics Tests") + class MemoryStatisticsTests { + + @Test + @DisplayName("Should set and get total memory correctly") + void shouldSetAndGetTotalMemoryCorrectly() { + GCStats stats = new GCStats(); + long totalMemory = 1024L * 1024L * 1024L; // 1GB + + stats.setTotalMemory(totalMemory); + assertEquals(totalMemory, stats.getTotalMemory(), "Total memory should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should set and get used memory correctly") + void shouldSetAndGetUsedMemoryCorrectly() { + GCStats stats = new GCStats(); + long usedMemory = 512L * 1024L * 1024L; // 512MB + + stats.setUsedMemory(usedMemory); + assertEquals(usedMemory, stats.getUsedMemory(), "Used memory should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should set and get free memory correctly") + void shouldSetAndGetFreeMemoryCorrectly() { + GCStats stats = new GCStats(); + long freeMemory = 256L * 1024L * 1024L; // 256MB + + stats.setFreeMemory(freeMemory); + assertEquals(freeMemory, stats.getFreeMemory(), "Free memory should be set and retrieved correctly"); + } + + @Test + @DisplayName("Should maintain memory relationship: total >= used") + void shouldMaintainMemoryRelationshipTotalGTEUsed() { + GCStats stats = new GCStats(); + long total = 1000L; + long used = 750L; + + stats.setTotalMemory(total); + stats.setUsedMemory(used); + + assertTrue(stats.getTotalMemory() >= stats.getUsedMemory(), "Total memory should be greater than or equal to used memory"); + } + + @Test + @DisplayName("Should maintain memory relationship: total >= free") + void shouldMaintainMemoryRelationshipTotalGTFree() { + GCStats stats = new GCStats(); + long total = 1000L; + long free = 300L; + + stats.setTotalMemory(total); + stats.setFreeMemory(free); + + assertTrue(stats.getTotalMemory() >= stats.getFreeMemory(), "Total memory should be greater than or equal to free memory"); + } + + @Test + @DisplayName("Should maintain memory relationship: total >= used + free") + void shouldMaintainMemoryRelationshipTotalGEUsedPlusFree() { + GCStats stats = new GCStats(); + long total = 1000L; + long used = 600L; + long free = 400L; + + stats.setTotalMemory(total); + stats.setUsedMemory(used); + stats.setFreeMemory(free); + + assertTrue(stats.getTotalMemory() >= stats.getUsedMemory() + stats.getFreeMemory(), + "Total memory should be greater than or equal to used + free memory"); + } + + @Test + @DisplayName("Should handle zero memory values") + void shouldHandleZeroMemoryValues() { + GCStats stats = new GCStats(); + + stats.setTotalMemory(0L); + stats.setUsedMemory(0L); + stats.setFreeMemory(0L); + + assertEquals(0L, stats.getTotalMemory(), "Total memory should handle zero"); + assertEquals(0L, stats.getUsedMemory(), "Used memory should handle zero"); + assertEquals(0L, stats.getFreeMemory(), "Free memory should handle zero"); + } + + @Test + @DisplayName("Should handle large memory values") + void shouldHandleLargeMemoryValues() { + GCStats stats = new GCStats(); + long largeValue = Long.MAX_VALUE / 2; // Half of max long value + + stats.setTotalMemory(largeValue); + stats.setUsedMemory(largeValue / 2); + stats.setFreeMemory(largeValue / 4); + + assertEquals(largeValue, stats.getTotalMemory(), "Large total memory should be handled"); + assertEquals(largeValue / 2, stats.getUsedMemory(), "Large used memory should be handled"); + assertEquals(largeValue / 4, stats.getFreeMemory(), "Large free memory should be handled"); + } + } + + @Nested + @DisplayName("Consistency Tests") + class ConsistencyTests { + + @Test + @DisplayName("Should maintain consistent state across multiple property changes") + void shouldMaintainConsistentStateAcrossMultiplePropertyChanges() { + GCStats stats = new GCStats(); + + // Set all properties + stats.setGcName("Test GC"); + stats.setCollectionCount(100L); + stats.setCollectionTime(5000L); + stats.setLastPauseDuration(50L); + stats.setRecentPauses(List.of(10L, 20L, 30L)); + stats.setPercentiles(new GCStats.PausePercentiles(15L, 25L, 40L, 60L, 100L)); + stats.setTotalMemory(1024L); + stats.setUsedMemory(512L); + stats.setFreeMemory(256L); + + // Verify all properties are still correct + assertEquals("Test GC", stats.getGcName()); + assertEquals(100L, stats.getCollectionCount()); + assertEquals(5000L, stats.getCollectionTime()); + assertEquals(50L, stats.getLastPauseDuration()); + assertEquals(List.of(10L, 20L, 30L), stats.getRecentPauses()); + assertEquals(15L, stats.getPercentiles().getP50()); + assertEquals(1024L, stats.getTotalMemory()); + assertEquals(512L, stats.getUsedMemory()); + assertEquals(256L, stats.getFreeMemory()); + } + + @Test + @DisplayName("Should handle independent property modifications") + void shouldHandleIndependentPropertyModifications() { + GCStats stats = new GCStats(); + + // Set initial values + stats.setCollectionCount(100L); + stats.setCollectionTime(5000L); + + // Modify one property + stats.setCollectionCount(200L); + + // Verify only the modified property changed + assertEquals(200L, stats.getCollectionCount(), "Modified property should change"); + assertEquals(5000L, stats.getCollectionTime(), "Unmodified property should remain unchanged"); + } + } + + @Nested + @DisplayName("Edge Cases Tests") + class EdgeCasesTests { + + @Test + @DisplayName("Should handle Long.MAX_VALUE for all numeric properties") + void shouldHandleLongMaxValueForAllNumericProperties() { + GCStats stats = new GCStats(); + long maxValue = Long.MAX_VALUE; + + stats.setCollectionCount(maxValue); + stats.setCollectionTime(maxValue); + stats.setLastPauseDuration(maxValue); + stats.setTotalMemory(maxValue); + stats.setUsedMemory(maxValue); + stats.setFreeMemory(maxValue); + + assertEquals(maxValue, stats.getCollectionCount()); + assertEquals(maxValue, stats.getCollectionTime()); + assertEquals(maxValue, stats.getLastPauseDuration()); + assertEquals(maxValue, stats.getTotalMemory()); + assertEquals(maxValue, stats.getUsedMemory()); + assertEquals(maxValue, stats.getFreeMemory()); + } + + @Test + @DisplayName("Should handle Long.MIN_VALUE for all numeric properties") + void shouldHandleLongMinValueForAllNumericProperties() { + GCStats stats = new GCStats(); + long minValue = Long.MIN_VALUE; + + stats.setCollectionCount(minValue); + stats.setCollectionTime(minValue); + stats.setLastPauseDuration(minValue); + stats.setTotalMemory(minValue); + stats.setUsedMemory(minValue); + stats.setFreeMemory(minValue); + + assertEquals(minValue, stats.getCollectionCount()); + assertEquals(minValue, stats.getCollectionTime()); + assertEquals(minValue, stats.getLastPauseDuration()); + assertEquals(minValue, stats.getTotalMemory()); + assertEquals(minValue, stats.getUsedMemory()); + assertEquals(minValue, stats.getFreeMemory()); + } } - } - - @Nested - @DisplayName("GC Name Tests") - class GCNameTests { - - @Test - @DisplayName("Should set and get GC name correctly") - void shouldSetAndGetGCNameCorrectly() { - GCStats stats = new GCStats(); - String gcName = "G1 Young Generation"; - - stats.setGcName(gcName); - assertEquals(gcName, stats.getGcName(), "GC name should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle null GC name") - void shouldHandleNullGCName() { - GCStats stats = new GCStats(); - - assertDoesNotThrow(() -> stats.setGcName(null), "Setting null GC name should not throw"); - assertNull(stats.getGcName(), "GC name should be null"); - } - - @Test - @DisplayName("Should handle empty GC name") - void shouldHandleEmptyGCName() { - GCStats stats = new GCStats(); - String emptyName = ""; - - stats.setGcName(emptyName); - assertEquals(emptyName, stats.getGcName(), "Empty GC name should be handled"); - } - - @Test - @DisplayName("Should handle special characters in GC name") - void shouldHandleSpecialCharactersInGCName() { - GCStats stats = new GCStats(); - String specialName = "G1/Young (Test) @#$%^&*()"; - - stats.setGcName(specialName); - assertEquals(specialName, stats.getGcName(), "Special characters should be preserved"); - } - } - - @Nested - @DisplayName("Collection Statistics Tests") - class CollectionStatisticsTests { - - @Test - @DisplayName("Should set and get collection count correctly") - void shouldSetAndGetCollectionCountCorrectly() { - GCStats stats = new GCStats(); - long collectionCount = 12345L; - - stats.setCollectionCount(collectionCount); - assertEquals( - collectionCount, - stats.getCollectionCount(), - "Collection count should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle zero collection count") - void shouldHandleZeroCollectionCount() { - GCStats stats = new GCStats(); - - stats.setCollectionCount(0L); - assertEquals(0L, stats.getCollectionCount(), "Zero collection count should be handled"); - } - - @Test - @DisplayName("Should handle negative collection count") - void shouldHandleNegativeCollectionCount() { - GCStats stats = new GCStats(); - long negativeCount = -100L; - - stats.setCollectionCount(negativeCount); - assertEquals( - negativeCount, stats.getCollectionCount(), "Negative collection count should be handled"); - } - - @Test - @DisplayName("Should handle very large collection count") - void shouldHandleVeryLargeCollectionCount() { - GCStats stats = new GCStats(); - long largeCount = Long.MAX_VALUE; - - stats.setCollectionCount(largeCount); - assertEquals( - largeCount, stats.getCollectionCount(), "Very large collection count should be handled"); - } - - @Test - @DisplayName("Should set and get collection time correctly") - void shouldSetAndGetCollectionTimeCorrectly() { - GCStats stats = new GCStats(); - long collectionTime = 98765L; - - stats.setCollectionTime(collectionTime); - assertEquals( - collectionTime, - stats.getCollectionTime(), - "Collection time should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle zero collection time") - void shouldHandleZeroCollectionTime() { - GCStats stats = new GCStats(); - - stats.setCollectionTime(0L); - assertEquals(0L, stats.getCollectionTime(), "Zero collection time should be handled"); - } - - @Test - @DisplayName("Should handle negative collection time") - void shouldHandleNegativeCollectionTime() { - GCStats stats = new GCStats(); - long negativeTime = -500L; - - stats.setCollectionTime(negativeTime); - assertEquals( - negativeTime, stats.getCollectionTime(), "Negative collection time should be handled"); - } - } - - @Nested - @DisplayName("Pause Duration Tests") - class PauseDurationTests { - - @Test - @DisplayName("Should set and get last pause duration correctly") - void shouldSetAndGetLastPauseDurationCorrectly() { - GCStats stats = new GCStats(); - long pauseDuration = 150L; - - stats.setLastPauseDuration(pauseDuration); - assertEquals( - pauseDuration, - stats.getLastPauseDuration(), - "Last pause duration should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle zero pause duration") - void shouldHandleZeroPauseDuration() { - GCStats stats = new GCStats(); - - stats.setLastPauseDuration(0L); - assertEquals(0L, stats.getLastPauseDuration(), "Zero pause duration should be handled"); - } - - @Test - @DisplayName("Should handle very long pause duration") - void shouldHandleVeryLongPauseDuration() { - GCStats stats = new GCStats(); - long longPause = 30000L; // 30 seconds - - stats.setLastPauseDuration(longPause); - assertEquals( - longPause, stats.getLastPauseDuration(), "Very long pause duration should be handled"); - } - - @Test - @DisplayName("Should handle microsecond-level pause duration") - void shouldHandleMicrosecondLevelPauseDuration() { - GCStats stats = new GCStats(); - long microPause = 1L; // 1 millisecond (micro in practice) - - stats.setLastPauseDuration(microPause); - assertEquals( - microPause, - stats.getLastPauseDuration(), - "Microsecond-level pause duration should be handled"); - } - } - - @Nested - @DisplayName("Recent Pauses Tests") - class RecentPausesTests { - - @Test - @DisplayName("Should set and get recent pauses list correctly") - void shouldSetAndGetRecentPausesListCorrectly() { - GCStats stats = new GCStats(); - List pauses = Arrays.asList(10L, 25L, 15L, 30L, 12L); - - stats.setRecentPauses(pauses); - assertEquals( - pauses, - stats.getRecentPauses(), - "Recent pauses list should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle empty recent pauses list") - void shouldHandleEmptyRecentPausesList() { - GCStats stats = new GCStats(); - List emptyList = List.of(); - - stats.setRecentPauses(emptyList); - assertEquals( - emptyList, stats.getRecentPauses(), "Empty recent pauses list should be handled"); - } - - @Test - @DisplayName("Should handle null recent pauses list") - void shouldHandleNullRecentPausesList() { - GCStats stats = new GCStats(); - - assertDoesNotThrow( - () -> stats.setRecentPauses(null), "Setting null recent pauses should not throw"); - assertNull(stats.getRecentPauses(), "Recent pauses should be null"); - } - - @Test - @DisplayName("Should handle recent pauses with zero values") - void shouldHandleRecentPausesWithZeroValues() { - GCStats stats = new GCStats(); - List zeros = Arrays.asList(0L, 0L, 0L, 0L); - - stats.setRecentPauses(zeros); - assertEquals(zeros, stats.getRecentPauses(), "Zero pause values should be handled"); - } - - @Test - @DisplayName("Should handle recent pauses with mixed values") - void shouldHandleRecentPausesWithMixedValues() { - GCStats stats = new GCStats(); - List mixedValues = Arrays.asList(5L, 0L, 1000L, 1L, 500L); - - stats.setRecentPauses(mixedValues); - assertEquals(mixedValues, stats.getRecentPauses(), "Mixed pause values should be handled"); - } - } - - @Nested - @DisplayName("Percentiles Tests") - class PercentilesTests { - - @Test - @DisplayName("Should set and get percentiles correctly") - void shouldSetAndGetPercentilesCorrectly() { - GCStats stats = new GCStats(); - GCStats.PausePercentiles percentiles = - new GCStats.PausePercentiles(10L, 25L, 50L, 100L, 200L); - - stats.setPercentiles(percentiles); - assertEquals( - percentiles, stats.getPercentiles(), "Percentiles should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should handle null percentiles") - void shouldHandleNullPercentiles() { - GCStats stats = new GCStats(); - - assertDoesNotThrow( - () -> stats.setPercentiles(null), "Setting null percentiles should not throw"); - assertNull(stats.getPercentiles(), "Percentiles should be null"); - } - - @Test - @DisplayName("Should handle all zero percentile values") - void shouldHandleAllZeroPercentileValues() { - GCStats stats = new GCStats(); - GCStats.PausePercentiles zeroPercentiles = new GCStats.PausePercentiles(0L, 0L, 0L, 0L, 0L); - - stats.setPercentiles(zeroPercentiles); - assertEquals(0L, stats.getPercentiles().getP50(), "P50 should be zero"); - assertEquals(0L, stats.getPercentiles().getP95(), "P95 should be zero"); - assertEquals(0L, stats.getPercentiles().getP99(), "P99 should be zero"); - assertEquals(0L, stats.getPercentiles().getP999(), "P999 should be zero"); - assertEquals(0L, stats.getPercentiles().getMax(), "Max should be zero"); - } - - @Test - @DisplayName("Should handle percentile with constructor") - void shouldHandlePercentileWithConstructor() { - long p50 = 15L, p95 = 50L, p99 = 120L, p999 = 300L, max = 500L; - GCStats.PausePercentiles percentiles = new GCStats.PausePercentiles(p50, p95, p99, p999, max); - - assertEquals(p50, percentiles.getP50(), "P50 should match constructor value"); - assertEquals(p95, percentiles.getP95(), "P95 should match constructor value"); - assertEquals(p99, percentiles.getP99(), "P99 should match constructor value"); - assertEquals(p999, percentiles.getP999(), "P999 should match constructor value"); - assertEquals(max, percentiles.getMax(), "Max should match constructor value"); - } - - @Test - @DisplayName("Should handle percentile setters and getters") - void shouldHandlePercentileSettersAndGetters() { - GCStats.PausePercentiles percentiles = new GCStats.PausePercentiles(); - - long p50 = 25L, p95 = 75L, p99 = 150L, p999 = 400L, max = 800L; - - percentiles.setP50(p50); - percentiles.setP95(p95); - percentiles.setP99(p99); - percentiles.setP999(p999); - percentiles.setMax(max); - - assertEquals(p50, percentiles.getP50(), "P50 should be set correctly"); - assertEquals(p95, percentiles.getP95(), "P95 should be set correctly"); - assertEquals(p99, percentiles.getP99(), "P99 should be set correctly"); - assertEquals(p999, percentiles.getP999(), "P999 should be set correctly"); - assertEquals(max, percentiles.getMax(), "Max should be set correctly"); - } - } - - @Nested - @DisplayName("Memory Statistics Tests") - class MemoryStatisticsTests { - - @Test - @DisplayName("Should set and get total memory correctly") - void shouldSetAndGetTotalMemoryCorrectly() { - GCStats stats = new GCStats(); - long totalMemory = 1024L * 1024L * 1024L; // 1GB - - stats.setTotalMemory(totalMemory); - assertEquals( - totalMemory, - stats.getTotalMemory(), - "Total memory should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should set and get used memory correctly") - void shouldSetAndGetUsedMemoryCorrectly() { - GCStats stats = new GCStats(); - long usedMemory = 512L * 1024L * 1024L; // 512MB - - stats.setUsedMemory(usedMemory); - assertEquals( - usedMemory, stats.getUsedMemory(), "Used memory should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should set and get free memory correctly") - void shouldSetAndGetFreeMemoryCorrectly() { - GCStats stats = new GCStats(); - long freeMemory = 256L * 1024L * 1024L; // 256MB - - stats.setFreeMemory(freeMemory); - assertEquals( - freeMemory, stats.getFreeMemory(), "Free memory should be set and retrieved correctly"); - } - - @Test - @DisplayName("Should maintain memory relationship: total >= used") - void shouldMaintainMemoryRelationshipTotalGTEUsed() { - GCStats stats = new GCStats(); - long total = 1000L; - long used = 750L; - - stats.setTotalMemory(total); - stats.setUsedMemory(used); - - assertTrue( - stats.getTotalMemory() >= stats.getUsedMemory(), - "Total memory should be greater than or equal to used memory"); - } - - @Test - @DisplayName("Should maintain memory relationship: total >= free") - void shouldMaintainMemoryRelationshipTotalGTFree() { - GCStats stats = new GCStats(); - long total = 1000L; - long free = 300L; - - stats.setTotalMemory(total); - stats.setFreeMemory(free); - - assertTrue( - stats.getTotalMemory() >= stats.getFreeMemory(), - "Total memory should be greater than or equal to free memory"); - } - - @Test - @DisplayName("Should maintain memory relationship: total >= used + free") - void shouldMaintainMemoryRelationshipTotalGEUsedPlusFree() { - GCStats stats = new GCStats(); - long total = 1000L; - long used = 600L; - long free = 400L; - - stats.setTotalMemory(total); - stats.setUsedMemory(used); - stats.setFreeMemory(free); - - assertTrue( - stats.getTotalMemory() >= stats.getUsedMemory() + stats.getFreeMemory(), - "Total memory should be greater than or equal to used + free memory"); - } - - @Test - @DisplayName("Should handle zero memory values") - void shouldHandleZeroMemoryValues() { - GCStats stats = new GCStats(); - - stats.setTotalMemory(0L); - stats.setUsedMemory(0L); - stats.setFreeMemory(0L); - - assertEquals(0L, stats.getTotalMemory(), "Total memory should handle zero"); - assertEquals(0L, stats.getUsedMemory(), "Used memory should handle zero"); - assertEquals(0L, stats.getFreeMemory(), "Free memory should handle zero"); - } - - @Test - @DisplayName("Should handle large memory values") - void shouldHandleLargeMemoryValues() { - GCStats stats = new GCStats(); - long largeValue = Long.MAX_VALUE / 2; // Half of max long value - - stats.setTotalMemory(largeValue); - stats.setUsedMemory(largeValue / 2); - stats.setFreeMemory(largeValue / 4); - - assertEquals(largeValue, stats.getTotalMemory(), "Large total memory should be handled"); - assertEquals(largeValue / 2, stats.getUsedMemory(), "Large used memory should be handled"); - assertEquals(largeValue / 4, stats.getFreeMemory(), "Large free memory should be handled"); - } - } - - @Nested - @DisplayName("Consistency Tests") - class ConsistencyTests { - - @Test - @DisplayName("Should maintain consistent state across multiple property changes") - void shouldMaintainConsistentStateAcrossMultiplePropertyChanges() { - GCStats stats = new GCStats(); - - // Set all properties - stats.setGcName("Test GC"); - stats.setCollectionCount(100L); - stats.setCollectionTime(5000L); - stats.setLastPauseDuration(50L); - stats.setRecentPauses(List.of(10L, 20L, 30L)); - stats.setPercentiles(new GCStats.PausePercentiles(15L, 25L, 40L, 60L, 100L)); - stats.setTotalMemory(1024L); - stats.setUsedMemory(512L); - stats.setFreeMemory(256L); - - // Verify all properties are still correct - assertEquals("Test GC", stats.getGcName()); - assertEquals(100L, stats.getCollectionCount()); - assertEquals(5000L, stats.getCollectionTime()); - assertEquals(50L, stats.getLastPauseDuration()); - assertEquals(List.of(10L, 20L, 30L), stats.getRecentPauses()); - assertEquals(15L, stats.getPercentiles().getP50()); - assertEquals(1024L, stats.getTotalMemory()); - assertEquals(512L, stats.getUsedMemory()); - assertEquals(256L, stats.getFreeMemory()); - } - - @Test - @DisplayName("Should handle independent property modifications") - void shouldHandleIndependentPropertyModifications() { - GCStats stats = new GCStats(); - - // Set initial values - stats.setCollectionCount(100L); - stats.setCollectionTime(5000L); - - // Modify one property - stats.setCollectionCount(200L); - - // Verify only the modified property changed - assertEquals(200L, stats.getCollectionCount(), "Modified property should change"); - assertEquals(5000L, stats.getCollectionTime(), "Unmodified property should remain unchanged"); - } - } - - @Nested - @DisplayName("Edge Cases Tests") - class EdgeCasesTests { - - @Test - @DisplayName("Should handle Long.MAX_VALUE for all numeric properties") - void shouldHandleLongMaxValueForAllNumericProperties() { - GCStats stats = new GCStats(); - long maxValue = Long.MAX_VALUE; - - stats.setCollectionCount(maxValue); - stats.setCollectionTime(maxValue); - stats.setLastPauseDuration(maxValue); - stats.setTotalMemory(maxValue); - stats.setUsedMemory(maxValue); - stats.setFreeMemory(maxValue); - - assertEquals(maxValue, stats.getCollectionCount()); - assertEquals(maxValue, stats.getCollectionTime()); - assertEquals(maxValue, stats.getLastPauseDuration()); - assertEquals(maxValue, stats.getTotalMemory()); - assertEquals(maxValue, stats.getUsedMemory()); - assertEquals(maxValue, stats.getFreeMemory()); - } - - @Test - @DisplayName("Should handle Long.MIN_VALUE for all numeric properties") - void shouldHandleLongMinValueForAllNumericProperties() { - GCStats stats = new GCStats(); - long minValue = Long.MIN_VALUE; - - stats.setCollectionCount(minValue); - stats.setCollectionTime(minValue); - stats.setLastPauseDuration(minValue); - stats.setTotalMemory(minValue); - stats.setUsedMemory(minValue); - stats.setFreeMemory(minValue); - - assertEquals(minValue, stats.getCollectionCount()); - assertEquals(minValue, stats.getCollectionTime()); - assertEquals(minValue, stats.getLastPauseDuration()); - assertEquals(minValue, stats.getTotalMemory()); - assertEquals(minValue, stats.getUsedMemory()); - assertEquals(minValue, stats.getFreeMemory()); - } - } } diff --git a/src/test/java/fish/payara/trader/monitoring/SLAMonitorServiceTest.java b/src/test/java/fish/payara/trader/monitoring/SLAMonitorServiceTest.java index afbda1f..cda483d 100644 --- a/src/test/java/fish/payara/trader/monitoring/SLAMonitorServiceTest.java +++ b/src/test/java/fish/payara/trader/monitoring/SLAMonitorServiceTest.java @@ -9,111 +9,111 @@ @DisplayName("SLAMonitorService Tests") class SLAMonitorServiceTest { - private SLAMonitorService slaMonitorService; - - @BeforeEach - void setUp() { - slaMonitorService = new SLAMonitorService(); - } - - @Test - @DisplayName("Should initialize with zeroed stats") - void shouldInitializeWithZeroedStats() { - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - - assertEquals(0, stats.totalOperations); - assertEquals(0, stats.violationsOver10ms); - assertEquals(0, stats.violationsOver50ms); - assertEquals(0, stats.violationsOver100ms); - assertEquals(0.0, stats.violationRate); - assertEquals(0, stats.recentViolations); - } - - @Test - @DisplayName("Should record normal operation below thresholds") - void shouldRecordNormalOperationBelowThresholds() { - slaMonitorService.recordOperation(5); - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(1, stats.totalOperations); - assertEquals(0, stats.violationsOver10ms); - assertEquals(0.0, stats.violationRate); - } - - @Test - @DisplayName("Should record violation over 10ms") - void shouldRecordViolationOver10ms() { - slaMonitorService.recordOperation(15); - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(1, stats.totalOperations); - assertEquals(1, stats.violationsOver10ms); - assertEquals(0, stats.violationsOver50ms); - assertEquals(0, stats.violationsOver100ms); - assertEquals(100.0, stats.violationRate); - assertEquals(1, stats.recentViolations); - } - - @Test - @DisplayName("Should record violation over 50ms") - void shouldRecordViolationOver50ms() { - slaMonitorService.recordOperation(55); - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(1, stats.totalOperations); - assertEquals(1, stats.violationsOver10ms); - assertEquals(1, stats.violationsOver50ms); - assertEquals(0, stats.violationsOver100ms); - assertEquals(1, stats.recentViolations); - } - - @Test - @DisplayName("Should record violation over 100ms") - void shouldRecordViolationOver100ms() { - slaMonitorService.recordOperation(105); - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(1, stats.totalOperations); - assertEquals(1, stats.violationsOver10ms); - assertEquals(1, stats.violationsOver50ms); - assertEquals(1, stats.violationsOver100ms); - assertEquals(1, stats.recentViolations); - } - - @Test - @DisplayName("Should calculate violation rate correctly") - void shouldCalculateViolationRateCorrectly() { - slaMonitorService.recordOperation(5); // No violation - slaMonitorService.recordOperation(15); // Violation > 10ms - slaMonitorService.recordOperation(5); // No violation - slaMonitorService.recordOperation(20); // Violation > 10ms - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(4, stats.totalOperations); - assertEquals(2, stats.violationsOver10ms); - assertEquals(50.0, stats.violationRate); - } - - @Test - @DisplayName("Should reset statistics") - void shouldResetStatistics() { - slaMonitorService.recordOperation(105); - slaMonitorService.reset(); - - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(0, stats.totalOperations); - assertEquals(0, stats.violationsOver10ms); - assertEquals(0, stats.recentViolations); - } - - @Test - @DisplayName("Should handle multiple violations in a window") - void shouldHandleMultipleViolationsInWindow() { - for (int i = 0; i < 10; i++) { - slaMonitorService.recordOperation(15); + private SLAMonitorService slaMonitorService; + + @BeforeEach + void setUp() { + slaMonitorService = new SLAMonitorService(); + } + + @Test + @DisplayName("Should initialize with zeroed stats") + void shouldInitializeWithZeroedStats() { + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + + assertEquals(0, stats.totalOperations); + assertEquals(0, stats.violationsOver10ms); + assertEquals(0, stats.violationsOver50ms); + assertEquals(0, stats.violationsOver100ms); + assertEquals(0.0, stats.violationRate); + assertEquals(0, stats.recentViolations); + } + + @Test + @DisplayName("Should record normal operation below thresholds") + void shouldRecordNormalOperationBelowThresholds() { + slaMonitorService.recordOperation(5); + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(1, stats.totalOperations); + assertEquals(0, stats.violationsOver10ms); + assertEquals(0.0, stats.violationRate); + } + + @Test + @DisplayName("Should record violation over 10ms") + void shouldRecordViolationOver10ms() { + slaMonitorService.recordOperation(15); + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(1, stats.totalOperations); + assertEquals(1, stats.violationsOver10ms); + assertEquals(0, stats.violationsOver50ms); + assertEquals(0, stats.violationsOver100ms); + assertEquals(100.0, stats.violationRate); + assertEquals(1, stats.recentViolations); + } + + @Test + @DisplayName("Should record violation over 50ms") + void shouldRecordViolationOver50ms() { + slaMonitorService.recordOperation(55); + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(1, stats.totalOperations); + assertEquals(1, stats.violationsOver10ms); + assertEquals(1, stats.violationsOver50ms); + assertEquals(0, stats.violationsOver100ms); + assertEquals(1, stats.recentViolations); } - SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); - assertEquals(10, stats.recentViolations); - } + @Test + @DisplayName("Should record violation over 100ms") + void shouldRecordViolationOver100ms() { + slaMonitorService.recordOperation(105); + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(1, stats.totalOperations); + assertEquals(1, stats.violationsOver10ms); + assertEquals(1, stats.violationsOver50ms); + assertEquals(1, stats.violationsOver100ms); + assertEquals(1, stats.recentViolations); + } + + @Test + @DisplayName("Should calculate violation rate correctly") + void shouldCalculateViolationRateCorrectly() { + slaMonitorService.recordOperation(5); // No violation + slaMonitorService.recordOperation(15); // Violation > 10ms + slaMonitorService.recordOperation(5); // No violation + slaMonitorService.recordOperation(20); // Violation > 10ms + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(4, stats.totalOperations); + assertEquals(2, stats.violationsOver10ms); + assertEquals(50.0, stats.violationRate); + } + + @Test + @DisplayName("Should reset statistics") + void shouldResetStatistics() { + slaMonitorService.recordOperation(105); + slaMonitorService.reset(); + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(0, stats.totalOperations); + assertEquals(0, stats.violationsOver10ms); + assertEquals(0, stats.recentViolations); + } + + @Test + @DisplayName("Should handle multiple violations in a window") + void shouldHandleMultipleViolationsInWindow() { + for (int i = 0; i < 10; i++) { + slaMonitorService.recordOperation(15); + } + + SLAMonitorService.SLAStats stats = slaMonitorService.getStats(); + assertEquals(10, stats.recentViolations); + } } diff --git a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java index 221dceb..6dbf0db 100644 --- a/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java +++ b/src/test/java/fish/payara/trader/pressure/AllocationModeTest.java @@ -13,121 +13,110 @@ @DisplayName("AllocationMode Tests") class AllocationModeTest { - @Nested - @DisplayName("Enum Values Tests") - class EnumValuesTests { - - @Test - @DisplayName("Should have all required allocation modes") - void shouldHaveAllRequiredAllocationModes() { - AllocationMode[] modes = AllocationMode.values(); - assertEquals(6, modes.length, "Should have exactly 6 allocation modes"); - - assertTrue(containsMode(modes, AllocationMode.OFF), "Should contain OFF mode"); - assertTrue( - containsMode(modes, AllocationMode.STEADY_LOAD), "Should contain STEADY_LOAD mode"); - assertTrue( - containsMode(modes, AllocationMode.GROWING_HEAP), "Should contain GROWING_HEAP mode"); - assertTrue( - containsMode(modes, AllocationMode.PROMOTION_STORM), - "Should contain PROMOTION_STORM mode"); - assertTrue( - containsMode(modes, AllocationMode.FRAGMENTATION), "Should contain FRAGMENTATION mode"); - assertTrue( - containsMode(modes, AllocationMode.CROSS_GEN_REFS), "Should contain CROSS_GEN_REFS mode"); + @Nested + @DisplayName("Enum Values Tests") + class EnumValuesTests { + + @Test + @DisplayName("Should have all required allocation modes") + void shouldHaveAllRequiredAllocationModes() { + AllocationMode[] modes = AllocationMode.values(); + assertEquals(6, modes.length, "Should have exactly 6 allocation modes"); + + assertTrue(containsMode(modes, AllocationMode.OFF), "Should contain OFF mode"); + assertTrue(containsMode(modes, AllocationMode.STEADY_LOAD), "Should contain STEADY_LOAD mode"); + assertTrue(containsMode(modes, AllocationMode.GROWING_HEAP), "Should contain GROWING_HEAP mode"); + assertTrue(containsMode(modes, AllocationMode.PROMOTION_STORM), "Should contain PROMOTION_STORM mode"); + assertTrue(containsMode(modes, AllocationMode.FRAGMENTATION), "Should contain FRAGMENTATION mode"); + assertTrue(containsMode(modes, AllocationMode.CROSS_GEN_REFS), "Should contain CROSS_GEN_REFS mode"); + } } - } - @Nested - @DisplayName("Scenario Properties Tests") - class ScenarioPropertiesTests { + @Nested + @DisplayName("Scenario Properties Tests") + class ScenarioPropertiesTests { - @ParameterizedTest - @EnumSource(AllocationMode.class) - @DisplayName("Should have non-null scenario type") - void shouldHaveNonNullScenarioType(AllocationMode mode) { - assertNotNull(mode.getScenarioType(), "ScenarioType should not be null"); - } + @ParameterizedTest + @EnumSource(AllocationMode.class) + @DisplayName("Should have non-null scenario type") + void shouldHaveNonNullScenarioType(AllocationMode mode) { + assertNotNull(mode.getScenarioType(), "ScenarioType should not be null"); + } - @Test - @DisplayName("Should have correct scenario types") - void shouldHaveCorrectScenarioTypes() { - assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); - assertEquals(ScenarioType.STEADY, AllocationMode.STEADY_LOAD.getScenarioType()); - assertEquals(ScenarioType.GROWING, AllocationMode.GROWING_HEAP.getScenarioType()); - assertEquals(ScenarioType.PROMOTION, AllocationMode.PROMOTION_STORM.getScenarioType()); - assertEquals(ScenarioType.FRAGMENTATION, AllocationMode.FRAGMENTATION.getScenarioType()); - assertEquals(ScenarioType.CROSS_REF, AllocationMode.CROSS_GEN_REFS.getScenarioType()); - } + @Test + @DisplayName("Should have correct scenario types") + void shouldHaveCorrectScenarioTypes() { + assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); + assertEquals(ScenarioType.STEADY, AllocationMode.STEADY_LOAD.getScenarioType()); + assertEquals(ScenarioType.GROWING, AllocationMode.GROWING_HEAP.getScenarioType()); + assertEquals(ScenarioType.PROMOTION, AllocationMode.PROMOTION_STORM.getScenarioType()); + assertEquals(ScenarioType.FRAGMENTATION, AllocationMode.FRAGMENTATION.getScenarioType()); + assertEquals(ScenarioType.CROSS_REF, AllocationMode.CROSS_GEN_REFS.getScenarioType()); + } - @ParameterizedTest - @EnumSource(AllocationMode.class) - @DisplayName("Should have valid allocation rates") - void shouldHaveValidAllocationRates(AllocationMode mode) { - assertTrue(mode.getAllocationRateMBPerSec() >= 0, "Allocation rate should be non-negative"); - } + @ParameterizedTest + @EnumSource(AllocationMode.class) + @DisplayName("Should have valid allocation rates") + void shouldHaveValidAllocationRates(AllocationMode mode) { + assertTrue(mode.getAllocationRateMBPerSec() >= 0, "Allocation rate should be non-negative"); + } - @ParameterizedTest - @EnumSource(AllocationMode.class) - @DisplayName("Should have meaningful descriptions") - void shouldHaveMeaningfulDescriptions(AllocationMode mode) { - String description = mode.getDescription(); + @ParameterizedTest + @EnumSource(AllocationMode.class) + @DisplayName("Should have meaningful descriptions") + void shouldHaveMeaningfulDescriptions(AllocationMode mode) { + String description = mode.getDescription(); - assertNotNull(description, "Description should not be null"); - assertFalse(description.trim().isEmpty(), "Description should not be empty"); - } - } - - @Nested - @DisplayName("Edge Cases Tests") - class EdgeCasesTests { - - @Test - @DisplayName("Should handle OFF mode correctly") - void shouldHandleOffModeCorrectly() { - assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); - assertEquals(0, AllocationMode.OFF.getLiveSetSizeMB()); - assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); + assertNotNull(description, "Description should not be null"); + assertFalse(description.trim().isEmpty(), "Description should not be empty"); + } } - @ParameterizedTest - @ValueSource(strings = {"OFF", "STEADY_LOAD", "GROWING_HEAP", "PROMOTION_STORM"}) - @DisplayName("Should handle enum valueOf correctly") - void shouldHandleEnumValueOfCorrectly(String modeName) { - assertDoesNotThrow( - () -> { - AllocationMode mode = AllocationMode.valueOf(modeName); - assertNotNull(mode, "Mode should not be null"); - assertEquals(modeName, mode.name(), "Mode name should match"); - }, - "valueOf should work for all valid mode names"); - } + @Nested + @DisplayName("Edge Cases Tests") + class EdgeCasesTests { + + @Test + @DisplayName("Should handle OFF mode correctly") + void shouldHandleOffModeCorrectly() { + assertEquals(0, AllocationMode.OFF.getAllocationRateMBPerSec()); + assertEquals(0, AllocationMode.OFF.getLiveSetSizeMB()); + assertEquals(ScenarioType.NONE, AllocationMode.OFF.getScenarioType()); + } - @Test - @DisplayName("Should throw IllegalArgumentException for invalid mode names") - void shouldThrowIllegalArgumentExceptionForInvalidModeNames() { - String[] invalidNames = {"INVALID", "low", "high", "", " ", null}; - - for (String invalidName : invalidNames) { - if (invalidName != null) { - assertThrows( - IllegalArgumentException.class, - () -> { - AllocationMode.valueOf(invalidName); - }, - () -> String.format("Should throw for invalid mode name: '%s'", invalidName)); + @ParameterizedTest + @ValueSource(strings = {"OFF", "STEADY_LOAD", "GROWING_HEAP", "PROMOTION_STORM"}) + @DisplayName("Should handle enum valueOf correctly") + void shouldHandleEnumValueOfCorrectly(String modeName) { + assertDoesNotThrow(() -> { + AllocationMode mode = AllocationMode.valueOf(modeName); + assertNotNull(mode, "Mode should not be null"); + assertEquals(modeName, mode.name(), "Mode name should match"); + }, "valueOf should work for all valid mode names"); + } + + @Test + @DisplayName("Should throw IllegalArgumentException for invalid mode names") + void shouldThrowIllegalArgumentExceptionForInvalidModeNames() { + String[] invalidNames = {"INVALID", "low", "high", "", " ", null}; + + for (String invalidName : invalidNames) { + if (invalidName != null) { + assertThrows(IllegalArgumentException.class, () -> { + AllocationMode.valueOf(invalidName); + }, () -> String.format("Should throw for invalid mode name: '%s'", invalidName)); + } + } } - } } - } - - /** Helper method to check if array contains specific mode */ - private boolean containsMode(AllocationMode[] modes, AllocationMode targetMode) { - for (AllocationMode mode : modes) { - if (mode == targetMode) { - return true; - } + + /** Helper method to check if array contains specific mode */ + private boolean containsMode(AllocationMode[] modes, AllocationMode targetMode) { + for (AllocationMode mode : modes) { + if (mode == targetMode) { + return true; + } + } + return false; } - return false; - } } diff --git a/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java b/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java index 863b737..23f23bc 100644 --- a/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/GCStatsResourceTest.java @@ -23,78 +23,82 @@ @DisplayName("GCStatsResource Tests") class GCStatsResourceTest { - @Mock private GCStatsService gcStatsService; - @Mock private MemoryPressureService memoryPressureService; - @Mock private MarketDataPublisher publisher; - @Mock private SLAMonitorService slaMonitor; - @Mock private GCPauseMonitor gcPauseMonitor; - - @InjectMocks private GCStatsResource resource; - - @Test - @DisplayName("Should return SLA stats") - void shouldReturnSLAStats() { - SLAMonitorService.SLAStats mockStats = new SLAMonitorService.SLAStats(100, 5, 2, 1, 5.0, 3); - when(slaMonitor.getStats()).thenReturn(mockStats); - - Response response = resource.getSLAStats(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - assertEquals(mockStats, response.getEntity()); - } - - @Test - @DisplayName("Should reset SLA stats") - void shouldResetSLAStats() { - Response response = resource.resetSLAStats(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(slaMonitor).reset(); - } - - @Test - @DisplayName("Should return GC pause stats") - void shouldReturnGCPauseStats() { - GCPauseMonitor.GCPauseStats mockStats = - new GCPauseMonitor.GCPauseStats(10, 100, 10.0, 10, 20, 30, 40, 50, 5, 2, 1, 10); - when(gcPauseMonitor.getStats()).thenReturn(mockStats); - - Response response = resource.getGCPauseStats(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - assertEquals(mockStats, response.getEntity()); - } - - @Test - @DisplayName("Should return accurate comparison data") - void shouldReturnAccurateComparisonData() { - when(memoryPressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); - when(publisher.getMessagesPublished()).thenReturn(5000L); - when(gcStatsService.collectGCStats()).thenReturn(Collections.emptyList()); - - GCPauseMonitor.GCPauseStats mockPauseStats = - new GCPauseMonitor.GCPauseStats(10, 100, 10.0, 10, 20, 30, 40, 50, 5, 2, 1, 10); - when(gcPauseMonitor.getStats()).thenReturn(mockPauseStats); - - Response response = resource.getComparison(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map entity = (Map) response.getEntity(); - - assertEquals(AllocationMode.STEADY_LOAD, entity.get("allocationMode")); - assertEquals(5000L, entity.get("messageRate")); - assertEquals(10.0, ((Number) entity.get("pauseP50Ms")).doubleValue()); - assertEquals(50L, entity.get("pauseMaxMs")); - assertEquals(5L, entity.get("slaViolations10ms")); - } - - @Test - @DisplayName("Should reset GC stats") - void shouldResetGCStats() { - Response response = resource.resetStats(); - - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(gcStatsService).resetStats(); - } + @Mock + private GCStatsService gcStatsService; + @Mock + private MemoryPressureService memoryPressureService; + @Mock + private MarketDataPublisher publisher; + @Mock + private SLAMonitorService slaMonitor; + @Mock + private GCPauseMonitor gcPauseMonitor; + + @InjectMocks + private GCStatsResource resource; + + @Test + @DisplayName("Should return SLA stats") + void shouldReturnSLAStats() { + SLAMonitorService.SLAStats mockStats = new SLAMonitorService.SLAStats(100, 5, 2, 1, 5.0, 3); + when(slaMonitor.getStats()).thenReturn(mockStats); + + Response response = resource.getSLAStats(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals(mockStats, response.getEntity()); + } + + @Test + @DisplayName("Should reset SLA stats") + void shouldResetSLAStats() { + Response response = resource.resetSLAStats(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + verify(slaMonitor).reset(); + } + + @Test + @DisplayName("Should return GC pause stats") + void shouldReturnGCPauseStats() { + GCPauseMonitor.GCPauseStats mockStats = new GCPauseMonitor.GCPauseStats(10, 100, 10.0, 10, 20, 30, 40, 50, 5, 2, 1, 10); + when(gcPauseMonitor.getStats()).thenReturn(mockStats); + + Response response = resource.getGCPauseStats(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals(mockStats, response.getEntity()); + } + + @Test + @DisplayName("Should return accurate comparison data") + void shouldReturnAccurateComparisonData() { + when(memoryPressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); + when(publisher.getMessagesPublished()).thenReturn(5000L); + when(gcStatsService.collectGCStats()).thenReturn(Collections.emptyList()); + + GCPauseMonitor.GCPauseStats mockPauseStats = new GCPauseMonitor.GCPauseStats(10, 100, 10.0, 10, 20, 30, 40, 50, 5, 2, 1, 10); + when(gcPauseMonitor.getStats()).thenReturn(mockPauseStats); + + Response response = resource.getComparison(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map entity = (Map) response.getEntity(); + + assertEquals(AllocationMode.STEADY_LOAD, entity.get("allocationMode")); + assertEquals(5000L, entity.get("messageRate")); + assertEquals(10.0, ((Number) entity.get("pauseP50Ms")).doubleValue()); + assertEquals(50L, entity.get("pauseMaxMs")); + assertEquals(5L, entity.get("slaViolations10ms")); + } + + @Test + @DisplayName("Should reset GC stats") + void shouldResetGCStats() { + Response response = resource.resetStats(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + verify(gcStatsService).resetStats(); + } } diff --git a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java index af99471..7dfd5c0 100644 --- a/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/MemoryPressureResourceTest.java @@ -18,61 +18,62 @@ @DisplayName("MemoryPressureResource Tests") class MemoryPressureResourceTest { - @Mock private MemoryPressureService pressureService; + @Mock + private MemoryPressureService pressureService; - @InjectMocks private MemoryPressureResource resource; + @InjectMocks + private MemoryPressureResource resource; - @Test - @DisplayName("Should return current status") - void shouldReturnCurrentStatus() { - when(pressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); - when(pressureService.isRunning()).thenReturn(true); + @Test + @DisplayName("Should return current status") + void shouldReturnCurrentStatus() { + when(pressureService.getCurrentMode()).thenReturn(AllocationMode.STEADY_LOAD); + when(pressureService.isRunning()).thenReturn(true); - Response response = resource.getStatus(); + Response response = resource.getStatus(); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map entity = (Map) response.getEntity(); - assertEquals("STEADY_LOAD", entity.get("currentMode")); - assertEquals(true, entity.get("running")); - } + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map entity = (Map) response.getEntity(); + assertEquals("STEADY_LOAD", entity.get("currentMode")); + assertEquals(true, entity.get("running")); + } - @Test - @DisplayName("Should set allocation mode successfully") - void shouldSetAllocationModeSuccessfully() { - Response response = resource.setMode("steady_load"); + @Test + @DisplayName("Should set allocation mode successfully") + void shouldSetAllocationModeSuccessfully() { + Response response = resource.setMode("steady_load"); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(pressureService).setAllocationMode(AllocationMode.STEADY_LOAD); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + verify(pressureService).setAllocationMode(AllocationMode.STEADY_LOAD); - @SuppressWarnings("unchecked") - Map entity = (Map) response.getEntity(); - assertTrue((Boolean) entity.get("success")); - assertEquals("STEADY_LOAD", entity.get("mode")); - } + @SuppressWarnings("unchecked") + Map entity = (Map) response.getEntity(); + assertTrue((Boolean) entity.get("success")); + assertEquals("STEADY_LOAD", entity.get("mode")); + } - @Test - @DisplayName("Should return bad request for invalid mode") - void shouldReturnBadRequestForInvalidMode() { - Response response = resource.setMode("invalid_mode"); + @Test + @DisplayName("Should return bad request for invalid mode") + void shouldReturnBadRequestForInvalidMode() { + Response response = resource.setMode("invalid_mode"); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map entity = (Map) response.getEntity(); - assertFalse((Boolean) entity.get("success")); - assertTrue(((String) entity.get("error")).contains("Invalid mode")); - } + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map entity = (Map) response.getEntity(); + assertFalse((Boolean) entity.get("success")); + assertTrue(((String) entity.get("error")).contains("Invalid mode")); + } - @Test - @DisplayName("Should return all modes") - void shouldReturnAllModes() { - Response response = resource.getModes(); + @Test + @DisplayName("Should return all modes") + void shouldReturnAllModes() { + Response response = resource.getModes(); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map> entity = - (Map>) response.getEntity(); - assertTrue(entity.containsKey("STEADY_LOAD")); - assertTrue(entity.containsKey("PROMOTION_STORM")); - } + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map> entity = (Map>) response.getEntity(); + assertTrue(entity.containsKey("STEADY_LOAD")); + assertTrue(entity.containsKey("PROMOTION_STORM")); + } } diff --git a/src/test/java/fish/payara/trader/rest/StatusResourceTest.java b/src/test/java/fish/payara/trader/rest/StatusResourceTest.java index 827c0a0..776ccac 100644 --- a/src/test/java/fish/payara/trader/rest/StatusResourceTest.java +++ b/src/test/java/fish/payara/trader/rest/StatusResourceTest.java @@ -21,359 +21,354 @@ @DisplayName("StatusResource Tests") class StatusResourceTest { - @Mock private AeronSubscriberBean subscriber; - - @Mock private MarketDataPublisher publisher; - - @Mock private MarketDataBroadcaster broadcaster; - - @InjectMocks private StatusResource statusResource; - - @Nested - @DisplayName("getStatus Method Tests") - class GetStatusMethodTests { - - @Test - @DisplayName("Should return complete status information") - void shouldReturnCompleteStatusInformation() { - // Arrange - String subscriberStatus = "Channel: aeron:ipc, Stream: 1001, Running: true"; - long localMessagesPublished = 5000L; - long clusterMessagesPublished = 25000L; - int activeSessions = 42; - String expectedInstanceName = "test-instance-1"; - - when(subscriber.getStatus()).thenReturn(subscriberStatus); - when(publisher.getMessagesPublished()).thenReturn(localMessagesPublished); - when(publisher.getClusterMessagesPublished()).thenReturn(clusterMessagesPublished); - when(broadcaster.getSessionCount()).thenReturn(activeSessions); - - // Set environment variable - note: tests can't modify real env vars, so we expect default - // behavior - // In this test, we expect "standalone" since we can't set actual environment variables - - try { - // Act - Response response = statusResource.getStatus(); - - // Assert - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - // Skip media type check as Response.getMediaType() may return null in tests - - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - - // Verify required fields - assertEquals("TradeStreamEE", status.get("application")); - assertEquals( - "High-frequency trading dashboard with Aeron and SBE", status.get("description")); - assertEquals("standalone", status.get("instance")); // Default value - assertEquals(subscriberStatus, status.get("subscriber")); - assertEquals("UP", status.get("status")); - - // Verify publisher stats - @SuppressWarnings("unchecked") - Map publisherStats = (Map) status.get("publisher"); - assertEquals(localMessagesPublished, publisherStats.get("localMessagesPublished")); - assertEquals(clusterMessagesPublished, publisherStats.get("clusterMessagesPublished")); - - // Verify websocket stats - @SuppressWarnings("unchecked") - Map websocketStats = (Map) status.get("websocket"); - assertEquals(activeSessions, websocketStats.get("activeSessions")); - - } finally { - // No cleanup needed since we can't modify env vars in tests - } - - // Verify mocks were called - verify(subscriber).getStatus(); - verify(publisher).getMessagesPublished(); - verify(publisher).getClusterMessagesPublished(); - verify(broadcaster).getSessionCount(); - } + @Mock + private AeronSubscriberBean subscriber; + + @Mock + private MarketDataPublisher publisher; + + @Mock + private MarketDataBroadcaster broadcaster; + + @InjectMocks + private StatusResource statusResource; + + @Nested + @DisplayName("getStatus Method Tests") + class GetStatusMethodTests { + + @Test + @DisplayName("Should return complete status information") + void shouldReturnCompleteStatusInformation() { + // Arrange + String subscriberStatus = "Channel: aeron:ipc, Stream: 1001, Running: true"; + long localMessagesPublished = 5000L; + long clusterMessagesPublished = 25000L; + int activeSessions = 42; + String expectedInstanceName = "test-instance-1"; + + when(subscriber.getStatus()).thenReturn(subscriberStatus); + when(publisher.getMessagesPublished()).thenReturn(localMessagesPublished); + when(publisher.getClusterMessagesPublished()).thenReturn(clusterMessagesPublished); + when(broadcaster.getSessionCount()).thenReturn(activeSessions); + + // Set environment variable - note: tests can't modify real env vars, so we expect default + // behavior + // In this test, we expect "standalone" since we can't set actual environment variables + + try { + // Act + Response response = statusResource.getStatus(); + + // Assert + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + // Skip media type check as Response.getMediaType() may return null in tests + + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + + // Verify required fields + assertEquals("TradeStreamEE", status.get("application")); + assertEquals("High-frequency trading dashboard with Aeron and SBE", status.get("description")); + assertEquals("standalone", status.get("instance")); // Default value + assertEquals(subscriberStatus, status.get("subscriber")); + assertEquals("UP", status.get("status")); + + // Verify publisher stats + @SuppressWarnings("unchecked") + Map publisherStats = (Map) status.get("publisher"); + assertEquals(localMessagesPublished, publisherStats.get("localMessagesPublished")); + assertEquals(clusterMessagesPublished, publisherStats.get("clusterMessagesPublished")); + + // Verify websocket stats + @SuppressWarnings("unchecked") + Map websocketStats = (Map) status.get("websocket"); + assertEquals(activeSessions, websocketStats.get("activeSessions")); + + } finally { + // No cleanup needed since we can't modify env vars in tests + } + + // Verify mocks were called + verify(subscriber).getStatus(); + verify(publisher).getMessagesPublished(); + verify(publisher).getClusterMessagesPublished(); + verify(broadcaster).getSessionCount(); + } - @Test - @DisplayName("Should use default instance name when environment variable is not set") - void shouldUseDefaultInstanceNameWhenEnvironmentVariableIsNotSet() { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - // Note: Tests can't modify real environment variables, so we expect default behavior - try { - // Act - Response response = statusResource.getStatus(); - - // Assert - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - assertEquals("standalone", status.get("instance"), "Should use default instance name"); - - } finally { - // No cleanup needed - } - } + @Test + @DisplayName("Should use default instance name when environment variable is not set") + void shouldUseDefaultInstanceNameWhenEnvironmentVariableIsNotSet() { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + // Note: Tests can't modify real environment variables, so we expect default behavior + try { + // Act + Response response = statusResource.getStatus(); + + // Assert + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + assertEquals("standalone", status.get("instance"), "Should use default instance name"); + + } finally { + // No cleanup needed + } + } - @Test - @DisplayName("Should handle null subscriber status gracefully") - void shouldHandleNullSubscriberStatusGracefully() { - // Arrange - when(subscriber.getStatus()).thenReturn(null); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - // Act - Response response = statusResource.getStatus(); - - // Assert - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - assertNull(status.get("subscriber"), "Null subscriber status should be handled"); - } + @Test + @DisplayName("Should handle null subscriber status gracefully") + void shouldHandleNullSubscriberStatusGracefully() { + // Arrange + when(subscriber.getStatus()).thenReturn(null); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + // Act + Response response = statusResource.getStatus(); + + // Assert + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + assertNull(status.get("subscriber"), "Null subscriber status should be handled"); + } - @Test - @DisplayName("Should handle zero values gracefully") - void shouldHandleZeroValuesGracefully() { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(0L); - when(publisher.getClusterMessagesPublished()).thenReturn(0L); - when(broadcaster.getSessionCount()).thenReturn(0); - - // Act - Response response = statusResource.getStatus(); - - // Assert - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - - @SuppressWarnings("unchecked") - Map publisherStats = (Map) status.get("publisher"); - assertEquals(0L, publisherStats.get("localMessagesPublished")); - assertEquals(0L, publisherStats.get("clusterMessagesPublished")); - - @SuppressWarnings("unchecked") - Map websocketStats = (Map) status.get("websocket"); - assertEquals(0, websocketStats.get("activeSessions")); - } + @Test + @DisplayName("Should handle zero values gracefully") + void shouldHandleZeroValuesGracefully() { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(0L); + when(publisher.getClusterMessagesPublished()).thenReturn(0L); + when(broadcaster.getSessionCount()).thenReturn(0); + + // Act + Response response = statusResource.getStatus(); + + // Assert + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + + @SuppressWarnings("unchecked") + Map publisherStats = (Map) status.get("publisher"); + assertEquals(0L, publisherStats.get("localMessagesPublished")); + assertEquals(0L, publisherStats.get("clusterMessagesPublished")); + + @SuppressWarnings("unchecked") + Map websocketStats = (Map) status.get("websocket"); + assertEquals(0, websocketStats.get("activeSessions")); + } - @Test - @DisplayName("Should handle very large values gracefully") - void shouldHandleVeryLargeValuesGracefully() { - // Arrange - long largeLocalMessages = Long.MAX_VALUE; - long largeClusterMessages = Long.MAX_VALUE - 1; - int largeSessions = Integer.MAX_VALUE - 1; // Leave room for additions - - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(largeLocalMessages); - when(publisher.getClusterMessagesPublished()).thenReturn(largeClusterMessages); - when(broadcaster.getSessionCount()).thenReturn(largeSessions); - - // Act - Response response = statusResource.getStatus(); - - // Assert - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - - @SuppressWarnings("unchecked") - Map publisherStats = (Map) status.get("publisher"); - assertEquals(largeLocalMessages, publisherStats.get("localMessagesPublished")); - assertEquals(largeClusterMessages, publisherStats.get("clusterMessagesPublished")); - - @SuppressWarnings("unchecked") - Map websocketStats = (Map) status.get("websocket"); - assertEquals(largeSessions, websocketStats.get("activeSessions")); + @Test + @DisplayName("Should handle very large values gracefully") + void shouldHandleVeryLargeValuesGracefully() { + // Arrange + long largeLocalMessages = Long.MAX_VALUE; + long largeClusterMessages = Long.MAX_VALUE - 1; + int largeSessions = Integer.MAX_VALUE - 1; // Leave room for additions + + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(largeLocalMessages); + when(publisher.getClusterMessagesPublished()).thenReturn(largeClusterMessages); + when(broadcaster.getSessionCount()).thenReturn(largeSessions); + + // Act + Response response = statusResource.getStatus(); + + // Assert + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + + @SuppressWarnings("unchecked") + Map publisherStats = (Map) status.get("publisher"); + assertEquals(largeLocalMessages, publisherStats.get("localMessagesPublished")); + assertEquals(largeClusterMessages, publisherStats.get("clusterMessagesPublished")); + + @SuppressWarnings("unchecked") + Map websocketStats = (Map) status.get("websocket"); + assertEquals(largeSessions, websocketStats.get("activeSessions")); + } } - } - @Nested - @DisplayName("getClusterStatus Method Tests") - class GetClusterStatusMethodTests { + @Nested + @DisplayName("getClusterStatus Method Tests") + class GetClusterStatusMethodTests { - @Test - @DisplayName("Should return standalone status when Hazelcast is null") - void shouldReturnStandaloneStatusWhenHazelcastIsNull() { - // Act - hazelcastInstance is injected as null in this test class + @Test + @DisplayName("Should return standalone status when Hazelcast is null") + void shouldReturnStandaloneStatusWhenHazelcastIsNull() { + // Act - hazelcastInstance is injected as null in this test class - // Act - Response response = statusResource.getClusterStatus(); + // Act + Response response = statusResource.getClusterStatus(); - // Assert - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - @SuppressWarnings("unchecked") - Map clusterInfo = (Map) response.getEntity(); + // Assert + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + @SuppressWarnings("unchecked") + Map clusterInfo = (Map) response.getEntity(); - assertFalse((Boolean) clusterInfo.get("clustered")); - assertEquals( - "Running in standalone mode (Hazelcast not available)", clusterInfo.get("message")); - } - } - - @Nested - @DisplayName("Dependency Injection Tests") - class DependencyInjectionTests { - - @Test - @DisplayName("Should properly inject all dependencies") - void shouldProperlyInjectAllDependencies() { - // Test that all mocks are properly injected - assertNotNull(subscriber, "Subscriber should be injected"); - assertNotNull(publisher, "Publisher should be injected"); - assertNotNull(broadcaster, "Broadcaster should be injected"); - assertNotNull(statusResource, "StatusResource should be created"); - } - } - - @Nested - @DisplayName("Response Format Tests") - class ResponseFormatTests { - - @Test - @DisplayName("Should always return JSON response") - void shouldAlwaysReturnJSONResponse() { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - // Act - Response statusResponse = statusResource.getStatus(); - Response clusterResponse = statusResource.getClusterStatus(); - - // Assert - skip media type checks as they may return null in tests - assertNotNull(statusResponse, "Status response should not be null"); - assertNotNull(clusterResponse, "Cluster response should not be null"); + assertFalse((Boolean) clusterInfo.get("clustered")); + assertEquals("Running in standalone mode (Hazelcast not available)", clusterInfo.get("message")); + } } - @Test - @DisplayName("Should always return success status codes for normal operations") - void shouldAlwaysReturnSuccessStatusCodesForNormalOperations() { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - // Act - Response statusResponse = statusResource.getStatus(); - Response clusterResponse = statusResource.getClusterStatus(); - - // Assert - assertEquals(Response.Status.OK.getStatusCode(), statusResponse.getStatus()); - assertEquals(Response.Status.OK.getStatusCode(), clusterResponse.getStatus()); + @Nested + @DisplayName("Dependency Injection Tests") + class DependencyInjectionTests { + + @Test + @DisplayName("Should properly inject all dependencies") + void shouldProperlyInjectAllDependencies() { + // Test that all mocks are properly injected + assertNotNull(subscriber, "Subscriber should be injected"); + assertNotNull(publisher, "Publisher should be injected"); + assertNotNull(broadcaster, "Broadcaster should be injected"); + assertNotNull(statusResource, "StatusResource should be created"); + } } - } - - @Nested - @DisplayName("Environment Variable Tests") - class EnvironmentVariableTests { - - @Test - @DisplayName("Should handle different instance name environment variables") - void shouldHandleDifferentInstanceNameEnvironmentVariables() { - String[] testNames = { - "", " ", "\tinstance-1", "instance-1", "test-instance-123", "production-instance" - }; - - for (String instanceName : testNames) { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - // Note: Tests can't modify real environment variables, so we always expect "standalone" - try { - // Act - Response response = statusResource.getStatus(); - - // Assert - @SuppressWarnings("unchecked") - Map status = (Map) response.getEntity(); - assertEquals("standalone", status.get("instance")); - - } finally { - // No cleanup needed + + @Nested + @DisplayName("Response Format Tests") + class ResponseFormatTests { + + @Test + @DisplayName("Should always return JSON response") + void shouldAlwaysReturnJSONResponse() { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + // Act + Response statusResponse = statusResource.getStatus(); + Response clusterResponse = statusResource.getClusterStatus(); + + // Assert - skip media type checks as they may return null in tests + assertNotNull(statusResponse, "Status response should not be null"); + assertNotNull(clusterResponse, "Cluster response should not be null"); + } + + @Test + @DisplayName("Should always return success status codes for normal operations") + void shouldAlwaysReturnSuccessStatusCodesForNormalOperations() { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + // Act + Response statusResponse = statusResource.getStatus(); + Response clusterResponse = statusResource.getClusterStatus(); + + // Assert + assertEquals(Response.Status.OK.getStatusCode(), statusResponse.getStatus()); + assertEquals(Response.Status.OK.getStatusCode(), clusterResponse.getStatus()); } - } } - } - - @Nested - @DisplayName("Edge Cases Tests") - class EdgeCasesTests { - - @Test - @DisplayName("Should handle multiple rapid calls correctly") - void shouldHandleMultipleRapidCallsCorrectly() { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L, 2000L, 3000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L, 10000L, 15000L); - when(broadcaster.getSessionCount()).thenReturn(10, 20, 30); - - // Act - Response response1 = statusResource.getStatus(); - Response response2 = statusResource.getStatus(); - Response response3 = statusResource.getStatus(); - - // Assert - All calls should succeed - assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); - assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); - assertEquals(Response.Status.OK.getStatusCode(), response3.getStatus()); - - // Verify mocks were called correct number of times - verify(publisher, times(3)).getMessagesPublished(); - verify(publisher, times(3)).getClusterMessagesPublished(); + + @Nested + @DisplayName("Environment Variable Tests") + class EnvironmentVariableTests { + + @Test + @DisplayName("Should handle different instance name environment variables") + void shouldHandleDifferentInstanceNameEnvironmentVariables() { + String[] testNames = {"", " ", "\tinstance-1", "instance-1", "test-instance-123", "production-instance"}; + + for (String instanceName : testNames) { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + // Note: Tests can't modify real environment variables, so we always expect "standalone" + try { + // Act + Response response = statusResource.getStatus(); + + // Assert + @SuppressWarnings("unchecked") + Map status = (Map) response.getEntity(); + assertEquals("standalone", status.get("instance")); + + } finally { + // No cleanup needed + } + } + } } - @Test - @DisplayName("Should handle concurrent access safely") - void shouldHandleConcurrentAccessSafely() throws InterruptedException { - // Arrange - when(subscriber.getStatus()).thenReturn("Running"); - when(publisher.getMessagesPublished()).thenReturn(1000L); - when(publisher.getClusterMessagesPublished()).thenReturn(5000L); - when(broadcaster.getSessionCount()).thenReturn(10); - - int threadCount = 10; - Thread[] threads = new Thread[threadCount]; - Response[] responses = new Response[threadCount]; - - // Act - for (int i = 0; i < threadCount; i++) { - final int index = i; - threads[i] = - new Thread( - () -> { - responses[index] = statusResource.getStatus(); + @Nested + @DisplayName("Edge Cases Tests") + class EdgeCasesTests { + + @Test + @DisplayName("Should handle multiple rapid calls correctly") + void shouldHandleMultipleRapidCallsCorrectly() { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L, 2000L, 3000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L, 10000L, 15000L); + when(broadcaster.getSessionCount()).thenReturn(10, 20, 30); + + // Act + Response response1 = statusResource.getStatus(); + Response response2 = statusResource.getStatus(); + Response response3 = statusResource.getStatus(); + + // Assert - All calls should succeed + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + assertEquals(Response.Status.OK.getStatusCode(), response3.getStatus()); + + // Verify mocks were called correct number of times + verify(publisher, times(3)).getMessagesPublished(); + verify(publisher, times(3)).getClusterMessagesPublished(); + } + + @Test + @DisplayName("Should handle concurrent access safely") + void shouldHandleConcurrentAccessSafely() throws InterruptedException { + // Arrange + when(subscriber.getStatus()).thenReturn("Running"); + when(publisher.getMessagesPublished()).thenReturn(1000L); + when(publisher.getClusterMessagesPublished()).thenReturn(5000L); + when(broadcaster.getSessionCount()).thenReturn(10); + + int threadCount = 10; + Thread[] threads = new Thread[threadCount]; + Response[] responses = new Response[threadCount]; + + // Act + for (int i = 0; i < threadCount; i++) { + final int index = i; + threads[i] = new Thread(() -> { + responses[index] = statusResource.getStatus(); }); - threads[i].start(); - } - - // Wait for all threads to complete - for (Thread thread : threads) { - thread.join(5000); - } - - // Assert - All responses should be successful - for (Response response : responses) { - assertNotNull(response, "Response should not be null"); - assertEquals( - Response.Status.OK.getStatusCode(), - response.getStatus(), - "All responses should be successful"); - } + threads[i].start(); + } + + // Wait for all threads to complete + for (Thread thread : threads) { + thread.join(5000); + } + + // Assert - All responses should be successful + for (Response response : responses) { + assertNotNull(response, "Response should not be null"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus(), "All responses should be successful"); + } + } } - } } diff --git a/src/test/java/fish/payara/trader/utils/GCTestUtil.java b/src/test/java/fish/payara/trader/utils/GCTestUtil.java index 6a8679b..ac14a77 100644 --- a/src/test/java/fish/payara/trader/utils/GCTestUtil.java +++ b/src/test/java/fish/payara/trader/utils/GCTestUtil.java @@ -11,193 +11,189 @@ /** Utility class for GC testing and simulation */ public class GCTestUtil { - private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); - private static final List gcBeans = - ManagementFactory.getGarbageCollectorMXBeans(); - - /** Captures initial GC statistics */ - public static GCStatistics captureInitialStats() { - long totalCollections = 0; - long totalTime = 0; - - for (GarbageCollectorMXBean gcBean : gcBeans) { - totalCollections += gcBean.getCollectionCount(); - totalTime += gcBean.getCollectionTime(); - } + private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); + private static final List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); - return new GCStatistics(totalCollections, totalTime, getHeapUsage()); - } + /** Captures initial GC statistics */ + public static GCStatistics captureInitialStats() { + long totalCollections = 0; + long totalTime = 0; - /** Calculates GC statistics after a test */ - public static GCStatistics calculateDelta(GCStatistics initial) { - long totalCollections = 0; - long totalTime = 0; + for (GarbageCollectorMXBean gcBean : gcBeans) { + totalCollections += gcBean.getCollectionCount(); + totalTime += gcBean.getCollectionTime(); + } - for (GarbageCollectorMXBean gcBean : gcBeans) { - totalCollections += gcBean.getCollectionCount(); - totalTime += gcBean.getCollectionTime(); + return new GCStatistics(totalCollections, totalTime, getHeapUsage()); } - return new GCStatistics( - totalCollections - initial.collections, totalTime - initial.time, getHeapUsage()); - } + /** Calculates GC statistics after a test */ + public static GCStatistics calculateDelta(GCStatistics initial) { + long totalCollections = 0; + long totalTime = 0; - /** Gets current heap usage */ - public static MemoryUsage getHeapUsage() { - return memoryBean.getHeapMemoryUsage(); - } + for (GarbageCollectorMXBean gcBean : gcBeans) { + totalCollections += gcBean.getCollectionCount(); + totalTime += gcBean.getCollectionTime(); + } - /** Allocates memory to trigger GC */ - public static void allocateMemory(int sizeMB) { - allocateMemory(sizeMB, 10); - } + return new GCStatistics(totalCollections - initial.collections, totalTime - initial.time, getHeapUsage()); + } - /** Allocates memory with controlled pattern */ - public static void allocateMemory(int sizeMB, int chunks) { - int chunkSize = (sizeMB * 1024 * 1024) / chunks; - List allocations = new ArrayList<>(); + /** Gets current heap usage */ + public static MemoryUsage getHeapUsage() { + return memoryBean.getHeapMemoryUsage(); + } + + /** Allocates memory to trigger GC */ + public static void allocateMemory(int sizeMB) { + allocateMemory(sizeMB, 10); + } - try { - for (int i = 0; i < chunks; i++) { - allocations.add(new byte[chunkSize]); + /** Allocates memory with controlled pattern */ + public static void allocateMemory(int sizeMB, int chunks) { + int chunkSize = (sizeMB * 1024 * 1024) / chunks; + List allocations = new ArrayList<>(); - // Small delay to simulate real usage pattern - if (i % 10 == 0) { - Thread.yield(); + try { + for (int i = 0; i < chunks; i++) { + allocations.add(new byte[chunkSize]); + + // Small delay to simulate real usage pattern + if (i % 10 == 0) { + Thread.yield(); + } + } + } finally { + // Let allocations go out of scope to trigger GC + allocations.clear(); } - } - } finally { - // Let allocations go out of scope to trigger GC - allocations.clear(); } - } - - /** Creates memory pressure in background thread */ - public static MemoryPressureThread createMemoryPressure( - int allocationRateMB, int durationSeconds) { - MemoryPressureThread pressureThread = - new MemoryPressureThread(allocationRateMB, durationSeconds); - return pressureThread; - } - - /** Forces a garbage collection and waits for completion */ - public static void forceGC() { - System.gc(); - System.runFinalization(); - - // Small delay to allow GC to complete - try { - Thread.sleep(100); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + + /** Creates memory pressure in background thread */ + public static MemoryPressureThread createMemoryPressure(int allocationRateMB, int durationSeconds) { + MemoryPressureThread pressureThread = new MemoryPressureThread(allocationRateMB, durationSeconds); + return pressureThread; } - } - /** Measures GC pause time for a specific operation */ - public static long measurePauseTime(Runnable operation) { - GCStatistics before = captureInitialStats(); + /** Forces a garbage collection and waits for completion */ + public static void forceGC() { + System.gc(); + System.runFinalization(); - long startTime = System.nanoTime(); - operation.run(); - long endTime = System.nanoTime(); + // Small delay to allow GC to complete + try { + Thread.sleep(100); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } - GCStatistics after = calculateDelta(before); + /** Measures GC pause time for a specific operation */ + public static long measurePauseTime(Runnable operation) { + GCStatistics before = captureInitialStats(); - return after.time; - } + long startTime = System.nanoTime(); + operation.run(); + long endTime = System.nanoTime(); - /** GC Statistics holder */ - public static class GCStatistics { - public final long collections; - public final long time; - public final MemoryUsage heapUsage; + GCStatistics after = calculateDelta(before); - public GCStatistics(long collections, long time, MemoryUsage heapUsage) { - this.collections = collections; - this.time = time; - this.heapUsage = heapUsage; + return after.time; } - @Override - public String toString() { - return String.format("GC{collections=%d, time=%dms, heap=%s}", collections, time, heapUsage); - } - } - - /** Background thread for creating controlled memory pressure */ - public static class MemoryPressureThread extends Thread { - private final int allocationRateMB; - private final int durationSeconds; - private final AtomicLong allocatedBytes = new AtomicLong(0); - private volatile boolean running = true; - - public MemoryPressureThread(int allocationRateMB, int durationSeconds) { - this.allocationRateMB = allocationRateMB; - this.durationSeconds = durationSeconds; - setDaemon(true); - setName("MemoryPressureThread"); - } + /** GC Statistics holder */ + public static class GCStatistics { + public final long collections; + public final long time; + public final MemoryUsage heapUsage; - @Override - public void run() { - long startTime = System.currentTimeMillis(); - long endTime = startTime + (durationSeconds * 1000L); + public GCStatistics(long collections, long time, MemoryUsage heapUsage) { + this.collections = collections; + this.time = time; + this.heapUsage = heapUsage; + } - int chunkSize = 1024 * 1024; // 1MB chunks - int allocationsPerSecond = allocationRateMB; - long allocationInterval = 1000L / allocationsPerSecond; // milliseconds + @Override + public String toString() { + return String.format("GC{collections=%d, time=%dms, heap=%s}", collections, time, heapUsage); + } + } - List allocations = new ArrayList<>(); + /** Background thread for creating controlled memory pressure */ + public static class MemoryPressureThread extends Thread { + private final int allocationRateMB; + private final int durationSeconds; + private final AtomicLong allocatedBytes = new AtomicLong(0); + private volatile boolean running = true; + + public MemoryPressureThread(int allocationRateMB, int durationSeconds) { + this.allocationRateMB = allocationRateMB; + this.durationSeconds = durationSeconds; + setDaemon(true); + setName("MemoryPressureThread"); + } - while (running && System.currentTimeMillis() < endTime) { - try { - allocations.add(new byte[chunkSize]); - allocatedBytes.addAndGet(chunkSize); + @Override + public void run() { + long startTime = System.currentTimeMillis(); + long endTime = startTime + (durationSeconds * 1000L); + + int chunkSize = 1024 * 1024; // 1MB chunks + int allocationsPerSecond = allocationRateMB; + long allocationInterval = 1000L / allocationsPerSecond; // milliseconds + + List allocations = new ArrayList<>(); + + while (running && System.currentTimeMillis() < endTime) { + try { + allocations.add(new byte[chunkSize]); + allocatedBytes.addAndGet(chunkSize); + + // Control allocation rate + if (allocationInterval > 0) { + Thread.sleep(allocationInterval); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } + + // Clear allocations to trigger GC + allocations.clear(); + allocatedBytes.set(0); + } - // Control allocation rate - if (allocationInterval > 0) { - Thread.sleep(allocationInterval); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; + public void stopPressure() { + running = false; + interrupt(); } - } - // Clear allocations to trigger GC - allocations.clear(); - allocatedBytes.set(0); + public long getAllocatedBytes() { + return allocatedBytes.get(); + } } - public void stopPressure() { - running = false; - interrupt(); - } + /** Wait for GC to occur within timeout */ + public static boolean waitForGC(long timeoutMillis) { + GCStatistics initial = captureInitialStats(); + long startTime = System.currentTimeMillis(); + + while (System.currentTimeMillis() - startTime < timeoutMillis) { + GCStatistics current = calculateDelta(initial); + if (current.collections > 0) { + return true; + } + + try { + Thread.sleep(10); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } - public long getAllocatedBytes() { - return allocatedBytes.get(); - } - } - - /** Wait for GC to occur within timeout */ - public static boolean waitForGC(long timeoutMillis) { - GCStatistics initial = captureInitialStats(); - long startTime = System.currentTimeMillis(); - - while (System.currentTimeMillis() - startTime < timeoutMillis) { - GCStatistics current = calculateDelta(initial); - if (current.collections > 0) { - return true; - } - - try { - Thread.sleep(10); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } + return false; } - - return false; - } } diff --git a/src/test/java/fish/payara/trader/websocket/MarketDataBroadcasterTest.java b/src/test/java/fish/payara/trader/websocket/MarketDataBroadcasterTest.java index c6ffa35..e50511d 100644 --- a/src/test/java/fish/payara/trader/websocket/MarketDataBroadcasterTest.java +++ b/src/test/java/fish/payara/trader/websocket/MarketDataBroadcasterTest.java @@ -18,140 +18,142 @@ @ExtendWith(MockitoExtension.class) class MarketDataBroadcasterTest { - private MarketDataBroadcaster broadcaster; + private MarketDataBroadcaster broadcaster; - @Mock private Session session1; + @Mock + private Session session1; - @Mock private Session session2; + @Mock + private Session session2; - @Mock private Async asyncRemote1; + @Mock + private Async asyncRemote1; - @Mock private Async asyncRemote2; + @Mock + private Async asyncRemote2; - @BeforeEach - void setUp() { - broadcaster = new MarketDataBroadcaster(); - lenient().when(session1.getId()).thenReturn("session-1"); - lenient().when(session2.getId()).thenReturn("session-2"); - lenient().when(session1.getAsyncRemote()).thenReturn(asyncRemote1); - lenient().when(session2.getAsyncRemote()).thenReturn(asyncRemote2); - lenient().when(session1.isOpen()).thenReturn(true); - lenient().when(session2.isOpen()).thenReturn(true); - } + @BeforeEach + void setUp() { + broadcaster = new MarketDataBroadcaster(); + lenient().when(session1.getId()).thenReturn("session-1"); + lenient().when(session2.getId()).thenReturn("session-2"); + lenient().when(session1.getAsyncRemote()).thenReturn(asyncRemote1); + lenient().when(session2.getAsyncRemote()).thenReturn(asyncRemote2); + lenient().when(session1.isOpen()).thenReturn(true); + lenient().when(session2.isOpen()).thenReturn(true); + } - @Test - void testAddSession() { - broadcaster.addSession(session1); + @Test + void testAddSession() { + broadcaster.addSession(session1); - assertThat(broadcaster.getSessionCount()).isEqualTo(1); - } + assertThat(broadcaster.getSessionCount()).isEqualTo(1); + } - @Test - void testAddMultipleSessions() { - broadcaster.addSession(session1); - broadcaster.addSession(session2); + @Test + void testAddMultipleSessions() { + broadcaster.addSession(session1); + broadcaster.addSession(session2); - assertThat(broadcaster.getSessionCount()).isEqualTo(2); - } + assertThat(broadcaster.getSessionCount()).isEqualTo(2); + } - @Test - void testRemoveSession() { - broadcaster.addSession(session1); - broadcaster.addSession(session2); + @Test + void testRemoveSession() { + broadcaster.addSession(session1); + broadcaster.addSession(session2); - broadcaster.removeSession(session1); + broadcaster.removeSession(session1); - assertThat(broadcaster.getSessionCount()).isEqualTo(1); - } + assertThat(broadcaster.getSessionCount()).isEqualTo(1); + } - @Test - void testBroadcastToAllSessions() { - broadcaster.addSession(session1); - broadcaster.addSession(session2); + @Test + void testBroadcastToAllSessions() { + broadcaster.addSession(session1); + broadcaster.addSession(session2); - String message = "{\"type\":\"trade\",\"price\":100}"; - broadcaster.broadcast(message); + String message = "{\"type\":\"trade\",\"price\":100}"; + broadcaster.broadcast(message); - verify(asyncRemote1).sendText(eq(message)); - verify(asyncRemote2).sendText(eq(message)); - } + verify(asyncRemote1).sendText(eq(message)); + verify(asyncRemote2).sendText(eq(message)); + } - @Test - void testBroadcastRemovesClosedSessions() { - broadcaster.addSession(session1); - broadcaster.addSession(session2); + @Test + void testBroadcastRemovesClosedSessions() { + broadcaster.addSession(session1); + broadcaster.addSession(session2); - when(session1.isOpen()).thenReturn(false); + when(session1.isOpen()).thenReturn(false); - String message = "{\"type\":\"trade\",\"price\":100}"; - broadcaster.broadcast(message); + String message = "{\"type\":\"trade\",\"price\":100}"; + broadcaster.broadcast(message); - verify(asyncRemote1, never()).sendText(any()); - verify(asyncRemote2).sendText(eq(message)); + verify(asyncRemote1, never()).sendText(any()); + verify(asyncRemote2).sendText(eq(message)); - assertThat(broadcaster.getSessionCount()).isEqualTo(1); - } + assertThat(broadcaster.getSessionCount()).isEqualTo(1); + } - @Test - void testBroadcastHandlesFailure() { - broadcaster.addSession(session1); - broadcaster.addSession(session2); + @Test + void testBroadcastHandlesFailure() { + broadcaster.addSession(session1); + broadcaster.addSession(session2); - String message = "{\"type\":\"trade\",\"price\":100}"; + String message = "{\"type\":\"trade\",\"price\":100}"; - doThrow(new RuntimeException("Send failed")).when(asyncRemote1).sendText(message); + doThrow(new RuntimeException("Send failed")).when(asyncRemote1).sendText(message); - broadcaster.broadcast(message); + broadcaster.broadcast(message); - verify(asyncRemote2).sendText(eq(message)); - assertThat(broadcaster.getSessionCount()).isEqualTo(1); - } + verify(asyncRemote2).sendText(eq(message)); + assertThat(broadcaster.getSessionCount()).isEqualTo(1); + } - @Test - void testGetSessionCountWhenEmpty() { - assertThat(broadcaster.getSessionCount()).isEqualTo(0); - } + @Test + void testGetSessionCountWhenEmpty() { + assertThat(broadcaster.getSessionCount()).isEqualTo(0); + } - @Test - void testBroadcastWithArtificialLoad() { - broadcaster.addSession(session1); + @Test + void testBroadcastWithArtificialLoad() { + broadcaster.addSession(session1); - String baseMessage = "{\"type\":\"trade\",\"price\":100}"; - broadcaster.broadcastWithArtificialLoad(baseMessage); + String baseMessage = "{\"type\":\"trade\",\"price\":100}"; + broadcaster.broadcastWithArtificialLoad(baseMessage); - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); - verify(asyncRemote1).sendText(messageCaptor.capture()); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(asyncRemote1).sendText(messageCaptor.capture()); - String sentMessage = messageCaptor.getValue(); - assertThat(sentMessage).contains(baseMessage); - assertThat(sentMessage).contains("\"wrapped\""); - assertThat(sentMessage).contains("\"padding\""); - assertThat(sentMessage.length()).isGreaterThan(baseMessage.length()); - } + String sentMessage = messageCaptor.getValue(); + assertThat(sentMessage).contains(baseMessage); + assertThat(sentMessage).contains("\"wrapped\""); + assertThat(sentMessage).contains("\"padding\""); + assertThat(sentMessage.length()).isGreaterThan(baseMessage.length()); + } - @Test - void testConcurrentSessionManagement() throws InterruptedException { - int threadCount = 10; - Thread[] threads = new Thread[threadCount]; + @Test + void testConcurrentSessionManagement() throws InterruptedException { + int threadCount = 10; + Thread[] threads = new Thread[threadCount]; - for (int i = 0; i < threadCount; i++) { - final int index = i; - threads[i] = - new Thread( - () -> { + for (int i = 0; i < threadCount; i++) { + final int index = i; + threads[i] = new Thread(() -> { Session mockSession = mock(Session.class); when(mockSession.getId()).thenReturn("session-" + index); when(mockSession.getAsyncRemote()).thenReturn(mock(Async.class)); when(mockSession.isOpen()).thenReturn(true); broadcaster.addSession(mockSession); - }); - threads[i].start(); - } + }); + threads[i].start(); + } - for (Thread thread : threads) { - thread.join(); - } + for (Thread thread : threads) { + thread.join(); + } - assertThat(broadcaster.getSessionCount()).isEqualTo(threadCount); - } + assertThat(broadcaster.getSessionCount()).isEqualTo(threadCount); + } } From 125179e3ad7a14d1c8cffa4f7f0cbd5f35434d26 Mon Sep 17 00:00:00 2001 From: Luqman Saeed Date: Tue, 30 Dec 2025 13:45:09 +0000 Subject: [PATCH 5/6] copy spotless config file. Update presentation --- Dockerfile | 1 + Dockerfile.scale | 1 + Dockerfile.scale.standard | 1 + Dockerfile.standard | 1 + src/main/webapp/images/dashboard.png | Bin 0 -> 984291 bytes src/main/webapp/presentation.html | 437 +++++++++++++++++++++++---- 6 files changed, 387 insertions(+), 54 deletions(-) create mode 100644 src/main/webapp/images/dashboard.png diff --git a/Dockerfile b/Dockerfile index f4d748e..3d9852f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /app # Copy Maven wrapper and pom.xml first for better layer caching COPY mvnw . COPY mvnw.cmd . +COPY spotless ./spotless COPY .mvn .mvn COPY pom.xml . diff --git a/Dockerfile.scale b/Dockerfile.scale index dbaff61..6eb1664 100644 --- a/Dockerfile.scale +++ b/Dockerfile.scale @@ -9,6 +9,7 @@ COPY mvnw . COPY mvnw.cmd . COPY .mvn .mvn COPY pom.xml . +COPY spotless ./spotless RUN ./mvnw dependency:go-offline -B diff --git a/Dockerfile.scale.standard b/Dockerfile.scale.standard index 8ca0647..06bd66e 100644 --- a/Dockerfile.scale.standard +++ b/Dockerfile.scale.standard @@ -9,6 +9,7 @@ COPY mvnw . COPY mvnw.cmd . COPY .mvn .mvn COPY pom.xml . +COPY spotless ./spotless RUN ./mvnw dependency:go-offline -B diff --git a/Dockerfile.standard b/Dockerfile.standard index 0754372..1e2d9b3 100644 --- a/Dockerfile.standard +++ b/Dockerfile.standard @@ -9,6 +9,7 @@ COPY mvnw . COPY mvnw.cmd . COPY .mvn .mvn COPY pom.xml . +COPY spotless ./spotless RUN ./mvnw dependency:go-offline -B diff --git a/src/main/webapp/images/dashboard.png b/src/main/webapp/images/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ca0cb70d78836ae7eceb9176853219e339f1b813 GIT binary patch literal 984291 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᠅uixEaE-A2lt9!tq}{w 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