import promiseRetry from "promise-retry" ; import { logError , Timer } from "../utils" ; import { Client } from "./api" ; import { Batcher } from "./batcher" ; import { Metric } from "./model" ; const defaultRetryIntervalMS = 250 ; /**
 * Processor batches metrics, and sends them to the API periodically.
 */ export class Processor { private timer : Timer ; private batcher = new Batcher ( ) ; private loopPromise ? : Promise < void > ; param client param intervalMS param shouldRetryOnFail param retryInterval constructor ( private client , intervalMS , private shouldRetryOnFail , private retryInterval = defaultRetryIntervalMS ) { this . timer = new Timer ( intervalMS ) ; } /**
     * Start processing incoming metrics asynchronously.
     */ public startProcessing ( ) { if ( this . loopPromise !== undefined ) { return ; } this . timer . start ( ) ; this . loopPromise = this . sendMetricsLoop ( ) ; } /**
     * Add a new metric to be batched and sent.
     */ public addMetric ( metric ) { this . batcher . add ( metric ) ; } /**
     * Send any unprocessed metrics. Resolves on completion.
     */ public async flush ( ) { this . timer . complete ( ) ; if ( this . loopPromise === undefined ) { this . loopPromise = this . sendMetricsLoop ( ) ; } await this . loopPromise ; } private async sendMetricsLoop ( ) { while ( ! ( await this . timer . nextTimeout ( ) ) ) { const oldBatcher = this . batcher ; this . batcher = new Batcher ( ) ; const metrics = oldBatcher . toAPIMetrics ( ) ; if ( metrics . length === 0 ) { continue ; } try { await this . client . sendMetrics ( metrics ) ; } catch { if ( this . shouldRetryOnFail ) { this . batcher = oldBatcher ; } } } const finalMetrics = this . batcher . toAPIMetrics ( ) ; if ( finalMetrics . length === 0 ) { return ; } try { const options = { maxTimeout : this . retryInterval , minTimeout : this . retryInterval , retries : this . shouldRetryOnFail ? 2 : 0 , } ; await promiseRetry ( options , ( retry ) => this . client . sendMetrics ( finalMetrics ) . catch ( retry ) ) ; } catch { throw Error ( "Failed to send metrics to Datadog" ) ; } } }