GMI · TECHNOLOGY OBSERVATORY // ALL SYSTEMS NOMINAL
ENGINEERED BY LEOPARD DATA

Multi-Threaded Report Engine

High-performance parallel processing for generating comprehensive investment reports with rate-limited API calls.

THREAD ENGINE
rendering diagram…
flowchart TB
    A([Symbol List<br/>Request]):::ext --> B[Control Thread<br/>Job Queue Manager]:::app
    B --> C{{Token Bucket<br/>3000 calls per min}}:::app
    C -->|acquire token| D[Worker Thread 1]:::svc
    C -->|acquire token| E[Worker Thread 2]:::svc
    C -->|acquire token| F[Worker Thread N<br/>8-16 pool]:::svc
    D --> G[FMP API<br/>Call]:::ext
    E --> G
    F --> G
    G -->|response| H[Thread-safe<br/>Result Aggregation]:::svc
    H --> I{Retry<br/>needed?}:::app
    I -->|yes - auto retry| G
    I -->|no| J[Data Validation<br/>Cleanup]:::svc
    J --> K[(Excel - JSON<br/>Azure Blob)]:::data
    classDef app fill:#1f2630,stroke:#C0894E,color:#F3EFE8;
    classDef svc fill:#241c14,stroke:#E2B583,color:#F3EFE8;
    classDef data fill:#22201a,stroke:#C0894E,color:#EBD3AE;
    classDef ext fill:#1b1f27,stroke:#5A616B,color:#C4C0B8;
    classDef sec fill:#1d2733,stroke:#5cc8e0,color:#eafaff;
The report engine dispatches symbols from a control thread through a token-bucket rate limiter (3 000 calls/min) to a configurable worker pool of 8-16 threads, each making parallel FMP API calls before aggregating results into Excel and JSON reports.

Parallel Processing Architecture

The Grade My Investments Report Engine utilizes advanced multi-threading techniques to maximize throughput while respecting API rate limits:

Main Control Thread
Job Queue Manager
Rate Limiter Controller
Thread Pool Coordinator
Worker Thread Pool
Thread 1
Thread 2
Thread 3
Thread N
Configurable pool size based on VM resources
Rate-Limited API Layer
Token Bucket (3000/min)
FMP API Client
Request Queue

Why Multi-Threading?

Maximum Throughput

Process multiple symbols simultaneously, utilizing full API rate limit capacity of 3,000 calls per minute

  • Parallel symbol processing
  • Optimal resource utilization
  • Reduced total processing time
I/O Optimization

While one thread waits for API responses, others continue processing, eliminating idle time

  • Non-blocking operations
  • CPU utilization during I/O waits
  • Concurrent data processing
Scalable Architecture

Thread pool scales with VM resources, automatically adjusting to available CPU cores and memory

  • Dynamic thread allocation
  • Memory-aware processing
  • Resource monitoring
Fault Tolerance

Individual thread failures don't affect overall processing, with automatic retry mechanisms

  • Isolated failure handling
  • Automatic retry logic
  • Graceful degradation

Rate Limiting Implementation

Token Bucket Algorithm

The engine employs a sophisticated token bucket rate limiter to ensure API compliance:

// Rate Limiter Configuration
const int MAX_CALLS_PER_MINUTE = 3000;
const int BUCKET_CAPACITY = 3000;
const double REFILL_RATE = 50.0; // tokens per second

// Token acquisition before API calls
await rateLimiter.AcquireTokenAsync();
var apiResponse = await fmpClient.GetDataAsync(symbol);
375 tokens
Current bucket state
Smooth Rate Distribution

8.33 tokens per second ensures even distribution throughout the minute

Burst Handling

Bucket capacity allows for initial bursts while maintaining average rate

Automatic Backpressure

Threads automatically wait when bucket is empty, preventing rate violations

Parallel Processing Workflow

1
Job Initialization

System receives report generation request with symbol list and processing parameters

  • Parse symbol list from request
  • Validate symbols against database
  • Initialize job tracking metadata
2
Thread Pool Allocation

Determine optimal thread count based on VM resources and current system load

  • Assess available CPU cores
  • Check memory availability
  • Configure thread pool size
3
Parallel Symbol Processing

Distribute symbols across worker threads for concurrent processing

  • Queue symbols for processing
  • Acquire rate limit tokens
  • Execute API calls concurrently
4
Data Aggregation

Collect and consolidate results from all worker threads

  • Thread-safe result collection
  • Data validation and cleanup
  • Progress tracking updates
5
Report Generation

Generate final Excel and JSON reports with all processed data

  • Excel workbook creation
  • JSON data serialization
  • Upload to Azure Blob Storage
Performance Metrics
500
API Calls/Minute
8-16
Worker Threads
85%
CPU Utilization
2.5GB
Memory Usage
10x
Speed Improvement
99.9%
Success Rate
Virtual Machine Setup
CPU: 8 vCores (Intel Xeon)
RAM: 16 GB DDR4
Storage: 250 GB SSD
Network: 1 Gbps bandwidth
OS: Ubuntu 22.04 LTS
Runtime: .NET 10.0
Throughput Comparison
Single Thread
50 symbols/min
Multi-Thread
500 symbols/min
Thread Safety
  • Thread-safe collections for result aggregation
  • Async/await patterns for non-blocking operations
  • Immutable data structures where possible
  • Cancellation tokens for graceful shutdown
Error Handling
  • Automatic retries for failed API calls
  • Symbol skipping for invalid tickers
  • Detailed logging for troubleshooting
  • Health monitoring and alerts
  • Circuit breakers for service protection