Documentation

Timeline Feature

AI Powered
Back to Docs

Advertisement

Timeline Feature

Documentation & Guides

Riot API Timeline Data Integration

Overview

The Riot API Timeline Data Integration feature provides a robust internal data pipeline for fetching, processing, and storing League of Legends match timeline data. This data is used internally by RiftSurge's AI analysis features to provide deep insights into player performance and gameplay patterns.

Architecture

Core Components

1. Models - Eloquent models for timeline data storage

2. Services - Business logic for data processing and API interactions

3. Jobs - Asynchronous processing of timeline data

4. Events & Listeners - Automatic triggering of timeline fetching

5. Storage - Flexible file storage using Laravel Storage facade

Data Flow

ScrimGame Completed → Event → Listener → FetchTimelineDataJob → ProcessTimelineDataJob → Database Storage

Models

MatchTimeline

  • Purpose: Main timeline record for each match
  • Key Fields: match_id, riot_match_id, status, raw_file_path, processed_at
  • Relationships: Has many TimelineFrame

TimelineFrame

  • Purpose: Individual frames within a match timeline
  • Key Fields: timestamp, game_time
  • Relationships: Belongs to MatchTimeline, has many TimelineParticipantFrame and TimelineEvent

TimelineParticipantFrame

  • Purpose: Participant-specific data for each frame
  • Key Fields: participant_id, current_gold, total_gold, level, xp, minions_killed, position_x, position_y

TimelineEvent

  • Purpose: Events that occur during the match
  • Key Fields: event_type, timestamp, participant_id, victim_id, killer_id, position_x, position_y

TimelineSummary

  • Purpose: Aggregated statistics for each participant
  • Key Fields: participant_id, total_gold_earned, kills, deaths, assists, cs_at_10, cs_at_15

Services

TimelineDataService

  • Purpose: Main service for accessing processed timeline data
  • Key Methods:
  • getTimelineData(string $matchId): ?array - Get complete timeline data
  • getTimelineDataBatch(array $matchIds): array - Batch retrieval
  • getTimelineDataByTimeRange(string $matchId, int $startTime, int $endTime): ?array
  • getTimelineSummary(string $matchId): ?array

RiotApiTimelineService

  • Purpose: Handles Riot API interactions for timeline data
  • Key Methods:
  • fetchTimelineDataWithRetry(string $region, string $matchId): ?array
  • validateTimelineData(array $timelineData): bool
  • extractTimelineMetadata(array $timelineData): array

RiotApiStatusService

  • Purpose: Monitors Riot API health and error rates
  • Key Methods:
  • trackApiError(): void
  • isApiDown(): bool
  • getApiStatus(): string
  • shouldShowApiDownMessage(): bool

TimelineStorageService

  • Purpose: Manages raw timeline data file storage
  • Key Methods:
  • storeTimelineData(string $matchId, array $timelineData): string
  • getTimelineData(string $filePath): ?array
  • cleanupOldFiles(int $daysOld = 30): int

TimelineDataValidator

  • Purpose: Comprehensive validation of timeline data structure
  • Key Methods:
  • isValid(array $timelineData, string $matchId = '', string $region = ''): bool
  • getValidationSummary(array $timelineData, string $matchId, string $region): array

Jobs

FetchTimelineDataJob

  • Purpose: Fetches raw timeline data from Riot API
  • Queue: riot
  • Process: API call → validation → storage → dispatch ProcessTimelineDataJob

ProcessTimelineDataJob

  • Purpose: Processes raw timeline data into database
  • Queue: riot
  • Process: Read raw data → parse frames/events → store in database

RetryTimelineProcessingJob

  • Purpose: Retries failed timeline processing
  • Queue: riot
  • Process: Reset failed timelines → dispatch ProcessTimelineDataJob

Events & Listeners

ScrimGameCompleted Event

  • Trigger: When a ScrimGame's completed_at field is set
  • Purpose: Signal that a scrim game has finished

TriggerTimelineFetching Listener

  • Purpose: Automatically fetch timeline data when scrim games complete
  • Process: Check for Riot game ID → create MatchTimeline → dispatch FetchTimelineDataJob

Configuration

Services Configuration (config/services.php)

'riot' => [

'api_key' => env('RIOT_API_KEY'),

'base_url' => env('RIOT_API_BASE_URL', 'https://americas.api.riotgames.com'),

'timeout' => env('RIOT_API_TIMEOUT', 30),

'retry_attempts' => env('RIOT_API_RETRY_ATTEMPTS', 3),

'retry_delay' => env('RIOT_API_RETRY_DELAY', 1000),

'rate_limits' => [

'personal' => [

'requests_per_second' => 20,

'requests_per_two_minutes' => 100,

],

'application' => [

'requests_per_second' => 500,

'requests_per_two_minutes' => 30000,

],

],

'error_threshold' => env('RIOT_API_ERROR_THRESHOLD', 50),

'error_window_minutes' => env('RIOT_API_ERROR_WINDOW', 30),

'timeline' => [

'disk' => env('RIOT_TIMELINE_DISK', 'local'),

'cleanup_days' => env('RIOT_TIMELINE_CLEANUP_DAYS', 30),

],

],

Timeline Configuration (config/timeline.php)

return [

'cache' => [

'timeline_data_ttl' => env('TIMELINE_DATA_CACHE_TTL', 3600),

'timeline_stats_ttl' => env('TIMELINE_STATS_CACHE_TTL', 600),

],

'query' => [

'max_frames_limit' => env('TIMELINE_MAX_FRAMES_LIMIT', 1000),

],

];

Queue Configuration (config/queue.php)

'riot' => [

'driver' => 'redis',

'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

'queue' => 'riot',

'retry_after' => (int) env('RIOT_QUEUE_RETRY_AFTER', 300),

'block_for' => null,

'after_commit' => false,

],

Horizon Configuration (config/horizon.php)

'supervisor-riot' => [

'connection' => 'redis',

'queue' => ['riot'],

'balance' => 'auto',

'autoScalingStrategy' => 'time',

'maxProcesses' => 2, // Local: 2, Production: 10

'maxTime' => 0,

'maxJobs' => 0,

'memory' => 256,

'tries' => 3,

'timeout' => 300, // 5 minutes for Riot API calls

'nice' => 0,

],

Environment Variables

Riot API Configuration

RIOT_API_KEY=your_riot_api_key_here

RIOT_API_BASE_URL=https://americas.api.riotgames.com

RIOT_API_TIMEOUT=30

RIOT_API_RETRY_ATTEMPTS=3

RIOT_API_RETRY_DELAY=1000

Error Monitoring

RIOT_API_ERROR_THRESHOLD=50

RIOT_API_ERROR_WINDOW=30

Timeline Storage

RIOT_TIMELINE_DISK=local # local, s3, etc.

RIOT_TIMELINE_CLEANUP_DAYS=30

Timeline Caching

TIMELINE_DATA_CACHE_TTL=3600

TIMELINE_STATS_CACHE_TTL=600

TIMELINE_MAX_FRAMES_LIMIT=1000

Queue Configuration

RIOT_QUEUE_RETRY_AFTER=300

Usage Examples

Fetching Timeline Data

use App\Services\TimelineDataService;

$timelineService = app(TimelineDataService::class);

// Get complete timeline data

$timelineData = $timelineService->getTimelineData('NA1_1234567890');

// Get timeline data for specific time range

$timeRangeData = $timelineService->getTimelineDataByTimeRange(

'NA1_1234567890',

60000, // 1 minute

300000 // 5 minutes

);

// Get timeline summary

$summary = $timelineService->getTimelineSummary('NA1_1234567890');

// Batch retrieval

$batchData = $timelineService->getTimelineDataBatch([

'NA1_1234567890',

'NA1_1234567891',

'NA1_1234567892'

]);

Manual Timeline Fetching

use App\Jobs\FetchTimelineDataJob;

use App\Models\MatchTimeline;

// Create a new timeline record

$matchTimeline = MatchTimeline::create([

'match_id' => 'NA1_1234567890',

'riot_match_id' => 'NA1_1234567890',

'status' => 'pending',

]);

// Dispatch the fetch job

FetchTimelineDataJob::dispatch(

$matchTimeline->id,

'na1', // region

'NA1_1234567890' // match ID

);

API Status Monitoring

use App\Services\RiotApiStatusService;

$statusService = app(RiotApiStatusService::class);

// Check if API is down

if ($statusService->isApiDown()) {

echo "Riot API is currently down";

}

// Get detailed status

$status = $statusService->getDetailedStatus();

echo "Status: " . $status['status'];

echo "Error Count: " . $status['error_count'];

echo "Error Rate: " . $status['error_rate'] . "%";

Error Handling

Custom Exceptions

RiotApiException

  • Purpose: Riot API specific errors
  • Properties: statusCode, endpoint, response
  • Usage: Thrown when Riot API returns client/server errors

TimelineProcessingException

  • Purpose: Timeline processing errors
  • Properties: matchId, stage, context
  • Usage: Thrown during timeline data processing failures

Error Recovery

1. API Failures: Automatic retry with exponential backoff

2. Rate Limiting: Respects Retry-After headers

3. Data Validation: Comprehensive validation before processing

4. Job Failures: Automatic retry via RetryTimelineProcessingJob

Monitoring

Laravel Horizon

  • Queue Monitoring: Real-time queue status and job processing
  • Failed Jobs: Automatic retry and failure tracking
  • Performance Metrics: Job processing times and throughput

Laravel Nightwatch

  • Application Monitoring: Overall application health
  • Error Tracking: Exception monitoring and alerting
  • Performance Monitoring: Response times and resource usage

Logging

  • Structured Logging: All timeline operations are logged with context
  • Error Tracking: API errors and processing failures
  • Performance Logging: Processing times and data volumes

Testing

Test Coverage

  • Unit Tests: All services, models, and jobs
  • Integration Tests: End-to-end workflow testing
  • Performance Tests: Large data processing and concurrent operations

Running Tests

Run all timeline tests

php artisan test --filter="Timeline"

Run specific test files

php artisan test tests/Feature/TimelineIntegrationTest.php

php artisan test tests/Feature/TimelineProcessingPerformanceTest.php

Run unit tests

php artisan test tests/Feature/Unit/Services/TimelineDataServiceTest.php

Deployment

Prerequisites

1. Redis: Required for queue processing

2. Database: PostgreSQL/MySQL for timeline data storage

3. Storage: Local filesystem or S3 for raw timeline files

4. Riot API Key: Valid API key with appropriate permissions

Deployment Steps

1. Environment Setup: Configure all required environment variables

2. Database Migration: Run timeline table migrations

3. Queue Workers: Start Horizon or queue workers

4. Storage Configuration: Ensure storage disk is properly configured

5. Monitoring Setup: Configure Horizon and Nightwatch

Production Considerations

  • Queue Workers: Use Horizon for production queue management
  • Storage: Use S3 or similar for raw timeline file storage
  • Monitoring: Set up alerts for API failures and processing issues
  • Scaling: Adjust Horizon worker counts based on load

Troubleshooting

Common Issues

Timeline Data Not Processing

1. Check queue workers are running

2. Verify Riot API key is valid

3. Check for failed jobs in Horizon

4. Review logs for error messages

API Rate Limiting

1. Check current API usage

2. Verify rate limit configuration

3. Monitor Retry-After headers

4. Consider upgrading API tier

Storage Issues

1. Verify storage disk configuration

2. Check disk space availability

3. Ensure proper permissions

4. Test file operations manually

Debug Commands

Check queue status

php artisan horizon:status

View failed jobs

php artisan queue:failed

Test API connectivity

php artisan tinker

>> app(\App\Services\RiotApiTimelineService::class)->fetchTimelineDataWithRetry('na1', 'test-match-id')

Check timeline data

php artisan tinker

>> app(\App\Services\TimelineDataService::class)->getTimelineData('test-match-id')

Performance Optimization

Caching

  • Timeline Data: Cached for 1 hour by default
  • Statistics: Cached for 10 minutes
  • API Status: Cached for 5 minutes

Database Optimization

  • Indexes: Optimized for time-series queries
  • Eager Loading: Prevents N+1 query problems
  • Batch Processing: Efficient bulk operations

Queue Optimization

  • Dedicated Queue: Separate riot queue for API calls
  • Retry Logic: Exponential backoff for failed requests
  • Rate Limiting: Respects Riot API limits

Security Considerations

API Key Management

  • Environment Variables: Never hardcode API keys
  • Rotation: Regular API key rotation
  • Permissions: Minimal required permissions

Data Privacy

  • Internal Use Only: Timeline data is not exposed externally
  • Access Control: Internal service access only
  • Data Retention: Configurable cleanup policies

Input Validation

  • Comprehensive Validation: All timeline data is validated
  • Sanitization: Proper data sanitization
  • Error Handling: Secure error messages

Future Enhancements

Potential Improvements

1. Real-time Processing: WebSocket integration for live updates

2. Advanced Analytics: Machine learning integration

3. Data Export: Export timeline data for external analysis

4. Performance Metrics: Advanced performance tracking

5. Multi-region Support: Enhanced region handling

Scalability Considerations

1. Horizontal Scaling: Multiple queue workers

2. Database Sharding: Partition timeline data by region/date

3. CDN Integration: Faster timeline data delivery

4. Caching Layers: Multi-level caching strategy

Need help? Check our FAQ

Advertisement