UNPKG

@aws-lambda-powertools/batch

Version:

The batch processing package for the Powertools for AWS Lambda (TypeScript) library.

125 lines (124 loc) 4.9 kB
import { BatchProcessorSync } from './BatchProcessorSync.js'; import { SqsFifoProcessor } from './SqsFifoProcessor.js'; import { EventType } from './constants.js'; import { SqsFifoMessageGroupShortCircuitError, SqsFifoShortCircuitError, } from './errors.js'; /** * Batch processor for SQS FIFO queues * * This class extends the {@link BatchProcessorSync} class and provides * a mechanism to process records from SQS FIFO queues synchronously. * * By default, we will stop processing at the first failure and mark unprocessed messages as failed to preserve ordering. * * However, this behavior may not be optimal for customers who wish to proceed with processing messages from a different group ID. * * @example * ```typescript * import { * BatchProcessor, * EventType, * processPartialResponseSync, * } from '@aws-lambda-powertools/batch'; * import type { SQSRecord, SQSHandler } from 'aws-lambda'; * * const processor = new BatchProcessor(EventType.SQS); * * const recordHandler = async (record: SQSRecord): Promise<void> => { * const payload = JSON.parse(record.body); * }; * * export const handler: SQSHandler = async (event, context) => * processPartialResponseSync(event, recordHandler, processor, { * context, * }); * ``` */ class SqsFifoPartialProcessor extends BatchProcessorSync { /** * Processor for handling SQS FIFO message */ #processor; constructor() { super(EventType.SQS); this.#processor = new SqsFifoProcessor(); } /** * Handles a failure for a given record. * Adds the current group ID to the set of failed group IDs if `skipGroupOnError` is true. * @param record - The record that failed. * @param exception - The error that occurred. * @returns The failure response. */ failureHandler(record, exception) { this.#processor.processFailureForCurrentGroup(this.options); return super.failureHandler(record, exception); } /** * Process a record with a synchronous handler * * This method orchestrates the processing of a batch of records synchronously * for SQS FIFO queues. * * The method calls the prepare hook to initialize the processor and then * iterates over each record in the batch, processing them one by one. * * If one of them fails and `skipGroupOnError` is not true, the method short circuits * the processing and fails the remaining records in the batch. * * If one of them fails and `skipGroupOnError` is true, then the method fails the current record * if the message group has any previous failure, otherwise keeps processing. * * Then, it calls the clean hook to clean up the processor and returns the * processed records. */ processSync() { this.prepare(); this.#processor.prepare(); const processedRecords = []; let currentIndex = 0; for (const record of this.records) { this.#processor.setCurrentGroup(record.attributes?.MessageGroupId); if (this.#processor.shouldShortCircuit(this.failureMessages, this.options)) { return this.shortCircuitProcessing(currentIndex, processedRecords); } const result = this.#processor.shouldSkipCurrentGroup(this.options) ? this.#processFailRecord(record, new SqsFifoMessageGroupShortCircuitError()) : this.processRecordSync(record); processedRecords.push(result); currentIndex++; } this.clean(); return processedRecords; } /** * Starting from the first failure index, fail all remaining messages regardless * of their group ID. * * This short circuit mechanism is used when we detect a failed message in the batch. * * Since messages in a FIFO queue are processed in order, we must stop processing any * remaining messages in the batch to prevent out-of-order processing. * * @param firstFailureIndex Index of first message that failed * @param processedRecords Array of response items that have been processed both successfully and unsuccessfully */ shortCircuitProcessing(firstFailureIndex, processedRecords) { const remainingRecords = this.records.slice(firstFailureIndex); for (const record of remainingRecords) { this.#processFailRecord(record, new SqsFifoShortCircuitError()); } this.clean(); return processedRecords; } /** * Processes a fail record. * * @param record - The record that failed. * @param exception - The error that occurred. */ #processFailRecord(record, exception) { const data = this.toBatchType(record, this.eventType); return this.failureHandler(data, exception); } } export { SqsFifoPartialProcessor };