🔧 Wave 149 Phase 3-4: Service Panic Fix + JWT Debug Logging (Agent 413)

**Issue**: Backtesting service crashing with "transport error"
**Root Cause #3**: blocking_read() called in async context causing panic

## Fixes Applied

### Agent 413: Async/Blocking Conflict Resolution
- **File**: services/backtesting_service/src/service.rs
- **Problem**: `blocking_read()` at line 237 panicked within Tokio runtime
- **Error**: "Cannot block the current thread from within a runtime"
- **Why Hard to Debug**: Panic manifested as gRPC transport error, not panic message
- **Fix**:
  - Line 215: Made validate_backtest_request() async
  - Line 237: Changed `blocking_read()` → `read().await`
  - Line 406: Added `.await` to function call
- **Impact**: Service stability restored, no more transport errors

### Debug Enhancement
- **File**: services/api_gateway/src/auth/interceptor.rs:362
- **Added**: Full token logging for JWT debugging
- **Purpose**: Debugging aid for Wave 149 investigation

## Technical Discovery
**Key Insight**: Async/blocking conflicts cause service crashes that appear as
transport errors at the client level. Always check service logs for panic
backtraces when debugging transport failures.

## Test Results
- Before: 29/49 (59.2%)
- After Phase 3-4: 29/49 (59.2%)
- Service Status: Stable (no more panics)

## Files Modified
- services/backtesting_service/src/service.rs (+3 lines async conversion)
- services/api_gateway/src/auth/interceptor.rs (+1 line debug logging)

Co-authored-by: Wave 149 Agent 413 (Service Panic Fix)
This commit is contained in:
jgrusewski
2025-10-12 19:57:54 +02:00
parent c6054218c8
commit 52c3862db9
2 changed files with 4 additions and 3 deletions

View File

@@ -212,7 +212,7 @@ impl BacktestingServiceImpl {
}
/// Validate backtest request parameters
fn validate_backtest_request(&self, request: &StartBacktestRequest) -> Result<(), Status> {
async fn validate_backtest_request(&self, request: &StartBacktestRequest) -> Result<(), Status> {
if request.strategy_name.is_empty() {
return Err(Status::invalid_argument("Strategy name cannot be empty"));
}
@@ -234,7 +234,7 @@ impl BacktestingServiceImpl {
}
// Check if we have capacity for new backtests
let active_count = self.active_backtests.blocking_read().len();
let active_count = self.active_backtests.read().await.len();
let max_concurrent = 10; // Default limit
if active_count >= max_concurrent {
return Err(Status::resource_exhausted(format!(
@@ -403,7 +403,7 @@ impl BacktestingService for BacktestingServiceImpl {
);
// Validate request
self.validate_backtest_request(&req)?;
self.validate_backtest_request(&req).await?;
// Generate backtest ID
let backtest_id = Self::generate_backtest_id();