* Sets up weight-based flushing for logs or metrics. * This helper function encapsulates the common pattern of: * 1. Tracking accumulated weight of items * 2. Flushing when weight exceeds threshold (800KB) * 3. Flushing after timeout period from the first item * * Uses closure variables to tra
( client: Client, afterCaptureHook: AfterCaptureHook, flushHook: FlushHook, estimateSizeFn: (item: T) => number, flushFn: (client: Client) => void, )
| 108 | * Uses closure variables to track weight and timeout state. |
| 109 | */ |
| 110 | function setupWeightBasedFlushing< |
| 111 | T, |
| 112 | AfterCaptureHook extends 'afterCaptureLog' | 'afterCaptureMetric', |
| 113 | FlushHook extends 'flushLogs' | 'flushMetrics', |
| 114 | >( |
| 115 | client: Client, |
| 116 | afterCaptureHook: AfterCaptureHook, |
| 117 | flushHook: FlushHook, |
| 118 | estimateSizeFn: (item: T) => number, |
| 119 | flushFn: (client: Client) => void, |
| 120 | ): void { |
| 121 | // Track weight and timeout in closure variables |
| 122 | let weight = 0; |
| 123 | let flushTimeout: ReturnType<typeof setTimeout> | undefined; |
| 124 | let isTimerActive = false; |
| 125 | |
| 126 | // @ts-expect-error - TypeScript can't narrow generic hook types to match specific overloads, but we know this is type-safe |
| 127 | client.on(flushHook, () => { |
| 128 | weight = 0; |
| 129 | clearTimeout(flushTimeout); |
| 130 | isTimerActive = false; |
| 131 | }); |
| 132 | |
| 133 | // @ts-expect-error - TypeScript can't narrow generic hook types to match specific overloads, but we know this is type-safe |
| 134 | client.on(afterCaptureHook, (item: T) => { |
| 135 | weight += estimateSizeFn(item); |
| 136 | |
| 137 | // We flush the buffer if it exceeds 0.8 MB |
| 138 | // The weight is a rough estimate, so we flush way before the payload gets too big. |
| 139 | if (weight >= 800_000) { |
| 140 | flushFn(client); |
| 141 | } else if (!isTimerActive) { |
| 142 | const flushInterval = client.getOptions()._flushInterval ?? DEFAULT_FLUSH_INTERVAL; |
| 143 | if (flushInterval > 0) { |
| 144 | // Only start timer if one isn't already running. |
| 145 | // This prevents flushing being delayed by items that arrive close to the timeout limit |
| 146 | // and thus resetting the flushing timeout and delaying items being flushed. |
| 147 | isTimerActive = true; |
| 148 | // Use safeUnref so the timer doesn't prevent the process from exiting |
| 149 | flushTimeout = safeUnref( |
| 150 | setTimeout(() => { |
| 151 | flushFn(client); |
| 152 | // Note: isTimerActive is reset by the flushHook handler above, not here, |
| 153 | // to avoid race conditions when new items arrive during the flush. |
| 154 | }, flushInterval), |
| 155 | ); |
| 156 | } |
| 157 | } |
| 158 | }); |
| 159 | |
| 160 | client.on('flush', () => { |
| 161 | flushFn(client); |
| 162 | }); |
| 163 | } |
| 164 | |
| 165 | /** |
| 166 | * Base implementation for all JavaScript SDK clients. |
no test coverage detected