feat(03-02): instrument processJob with fire-and-forget analytics events
- Add import for recordProcessingEvent from analyticsService - Emit upload_started after markAsProcessing (job processing start) - Emit completed with duration_ms after markAsCompleted (job success) - Emit failed with duration_ms and error_message in catch block (job failure) - All calls are void/fire-and-forget (no await) per PITFALL-6 constraint - Null-guard on job in catch block prevents runtime errors
This commit is contained in:
@@ -3,6 +3,7 @@ import { ProcessingJobModel, ProcessingJob } from '../models/ProcessingJobModel'
|
||||
import { DocumentModel } from '../models/DocumentModel';
|
||||
import { fileStorageService } from './fileStorageService';
|
||||
import { unifiedDocumentProcessor } from './unifiedDocumentProcessor';
|
||||
import { recordProcessingEvent } from './analyticsService';
|
||||
|
||||
export class JobProcessorService {
|
||||
private isProcessing = false;
|
||||
@@ -133,6 +134,13 @@ export class JobProcessorService {
|
||||
await ProcessingJobModel.markAsProcessing(jobId);
|
||||
jobStatusUpdated = true; // Track that we've updated status
|
||||
|
||||
// Analytics: job processing started (fire-and-forget, void return)
|
||||
recordProcessingEvent({
|
||||
document_id: job.document_id,
|
||||
user_id: job.user_id,
|
||||
event_type: 'upload_started',
|
||||
});
|
||||
|
||||
// Add timeout protection (28 minutes for API immediate processing, 14 for scheduled function)
|
||||
// API endpoint has 30-min Cloud Run timeout; scheduled function has 15 min
|
||||
const processingTimeout = 28 * 60 * 1000; // 28 minutes in milliseconds
|
||||
@@ -333,6 +341,14 @@ export class JobProcessorService {
|
||||
processingTime,
|
||||
attempts: job.attempts + 1,
|
||||
});
|
||||
|
||||
// Analytics: job completed (fire-and-forget, void return)
|
||||
recordProcessingEvent({
|
||||
document_id: job.document_id,
|
||||
user_id: job.user_id,
|
||||
event_type: 'completed',
|
||||
duration_ms: processingTime,
|
||||
});
|
||||
})(),
|
||||
timeoutPromise
|
||||
]);
|
||||
@@ -363,6 +379,18 @@ export class JobProcessorService {
|
||||
attempts: job ? job.attempts + 1 : 'unknown',
|
||||
});
|
||||
|
||||
// Analytics: job failed (fire-and-forget, void return)
|
||||
// Guard with job check — job is null if findById failed before assignment
|
||||
if (job) {
|
||||
recordProcessingEvent({
|
||||
document_id: job.document_id,
|
||||
user_id: job.user_id,
|
||||
event_type: 'failed',
|
||||
duration_ms: processingTime,
|
||||
error_message: errorMessage,
|
||||
});
|
||||
}
|
||||
|
||||
// Mark job as failed (will auto-retry if attempts < max_attempts)
|
||||
try {
|
||||
await ProcessingJobModel.markAsFailed(jobId, errorMessage);
|
||||
|
||||
Reference in New Issue
Block a user