"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.BindBatchTracker = exports.BatchTracker = void 0;
const client_utils_1 = require("@fluid-internal/client-utils");
const internal_1 = require("@fluidframework/core-utils/internal");
const internal_2 = require("@fluidframework/telemetry-utils/internal");
class BatchTracker {
    constructor(batchEventEmitter, logger, batchLengthThreshold, batchCountSamplingRate, dateTimeProvider = () => (0, client_utils_1.performanceNow)()) {
        this.batchEventEmitter = batchEventEmitter;
        this.trackedBatchCount = 0;
        this.logger = (0, internal_2.createChildLogger)({ logger, namespace: "Batching" });
        this.batchEventEmitter.on("batchBegin", (message) => {
            this.startBatchSequenceNumber = message.sequenceNumber;
            this.batchProcessingStartTimeStamp = dateTimeProvider();
            this.trackedBatchCount++;
        });
        this.batchEventEmitter.on("batchEnd", (error, message) => {
            (0, internal_1.assert)(this.startBatchSequenceNumber !== undefined &&
                this.batchProcessingStartTimeStamp !== undefined, 0x2ba /* "batchBegin must fire before batchEnd" */);
            const length = message.sequenceNumber - this.startBatchSequenceNumber + 1;
            if (length >= batchLengthThreshold) {
                this.logger.sendPerformanceEvent({
                    eventName: "LengthTooBig",
                    length,
                    threshold: batchLengthThreshold,
                    batchEndSequenceNumber: message.sequenceNumber,
                    duration: dateTimeProvider() - this.batchProcessingStartTimeStamp,
                    batchError: error !== undefined,
                });
            }
            if (this.trackedBatchCount % batchCountSamplingRate === 0) {
                this.logger.sendPerformanceEvent({
                    eventName: "Length",
                    length,
                    samplingRate: batchCountSamplingRate,
                    batchEndSequenceNumber: message.sequenceNumber,
                    duration: dateTimeProvider() - this.batchProcessingStartTimeStamp,
                });
            }
            this.startBatchSequenceNumber = undefined;
            this.batchProcessingStartTimeStamp = undefined;
        });
    }
}
exports.BatchTracker = BatchTracker;
/**
 * Track batch sizes in terms of op counts and processing times
 *
 * @param batchEventEmitter - event emitter which tracks the lifecycle of batch operations
 * @param logger - See {@link @fluidframework/core-interfaces#ITelemetryLoggerExt}
 * @param batchLengthThreshold - threshold for the length of a batch when to send an error event
 * @param batchCountSamplingRate - rate for batches for which to send an event with its characteristics
 */
const BindBatchTracker = (batchEventEmitter, logger, batchLengthThreshold = 1000, batchCountSamplingRate = 1000) => new BatchTracker(batchEventEmitter, logger, batchLengthThreshold, batchCountSamplingRate);
exports.BindBatchTracker = BindBatchTracker;
//# sourceMappingURL=batchTracker.js.map