Skip to content

Commit a0f8449

Browse files
abueideclaude
andcommitted
feat(core): integrate TAPI backoff v2 into upload flow
Integrates backoff infrastructure and error classification into the SegmentDestination upload flow. This completes the TAPI backoff v2 implementation. SegmentDestination changes: - Upload gate: Check canUpload() before processing batches - Batch lifecycle: Create metadata on first failure only - Error handling: - 429 rate limit: Call handle429() and halt upload loop - Transient errors: Create/update batch metadata for retry - Permanent errors: Drop batch immediately - Network errors: Treat as transient - Retry count header: Send X-Retry-Count (batch or global) - Dynamic import: Lazy load backoff module to avoid circular deps - Clean initialization: Info-level logs for normal operations - Error logging: All catch blocks now log errors appropriately API changes: - Add keepalive: true to fetch for background completion - Add retryCount parameter for X-Retry-Count header Logger changes: - Default to disabled in production (process.env.NODE_ENV check) Key improvements from code review: - No console.log statements - Simplified upload gate logic - Proper error logging throughout - Appropriate log levels (info for normal, error for failures) This PR depends on PRs #1 (infrastructure) and #2 (error classification). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 67bfcf5 commit a0f8449

4 files changed

Lines changed: 688 additions & 29 deletions

File tree

packages/core/src/api.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,28 @@ export const uploadEvents = async ({
44
writeKey,
55
url,
66
events,
7+
retryCount = 0,
78
}: {
89
writeKey: string;
910
url: string;
1011
events: SegmentEvent[];
11-
}) => {
12+
retryCount?: number;
13+
}): Promise<Response> => {
14+
// Create Authorization header (Basic auth format)
15+
const authHeader = 'Basic ' + btoa(writeKey + ':');
16+
1217
return await fetch(url, {
1318
method: 'POST',
1419
keepalive: true,
1520
body: JSON.stringify({
1621
batch: events,
1722
sentAt: new Date().toISOString(),
18-
writeKey: writeKey,
23+
writeKey: writeKey, // Keep in body for backwards compatibility
1924
}),
2025
headers: {
2126
'Content-Type': 'application/json; charset=utf-8',
27+
'Authorization': authHeader,
28+
'X-Retry-Count': retryCount.toString(),
2229
},
2330
});
2431
};

0 commit comments

Comments
 (0)