import { type Counter } from './process-id.js'; import { type InvalidEntry, type RecoverResult, type WalFormat, type WalRecord, WriteAheadLogFile } from './wal.js'; /** * Counter for generating sequential shard IDs. * Encapsulates the shard count increment logic. */ export declare const ShardedWalCounter: Counter; /** * Generates a unique readable instance ID. * This ID uniquely identifies a shard/file per process/thread combination with a human-readable timestamp. * Format: readable-timestamp.pid.threadId.counter * Example: "20240101-120000-000.12345.1.1" * * @returns A unique ID string with readable timestamp, process ID, thread ID, and counter */ export declare function getShardId(): string; /** * @TODO remove in PR https://github.com/code-pushup/cli/pull/1231 in favour of class method getShardedFileName * Generates a path to a shard file using human-readable IDs. * Both groupId and shardId are already in readable date format. * * Example with groupId "20240101-120000-000" and shardId "20240101-120000-000.12345.1.1": * Full path: /base/20240101-120000-000/trace.20240101-120000-000.12345.1.1.log * * @param opt.dir - The directory to store the shard file * @param opt.format - The WalFormat to use for the shard file * @param opt.groupId - The human-readable group ID (yyyymmdd-hhmmss-ms format) * @param opt.shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format) * @returns The path to the shard file */ export declare function getShardedPath(opt: { dir?: string; format: WalFormat; groupId: string; shardId: string; }): string; /** * Sharded Write-Ahead Log manager for coordinating multiple WAL shards. * Handles distributed logging across multiple processes/files with atomic finalization. */ export declare class ShardedWal { #private; static instanceCount: number; readonly groupId: string; /** * Initialize the given environment variable if not already set. * This must be done as early as possible before any user code runs. * Sets envVarName to the current instance ID if not already defined. * * @param envVarName - Environment variable name for storing coordinator ID * @param instanceID - The instance ID to set as coordinator */ static setCoordinatorProcess(envVarName: string, instanceID: string): void; /** * Determines if this process is the leader WAL process. * * The leader is the process that first enabled profiling over the given env var. * All descendant processes inherit the environment. * * @param envVarName - Environment variable name for storing coordinator ID * @param instanceID - The instance ID to check * @returns true if this is the leader WAL process, false otherwise */ static isCoordinatorProcess(envVarName: string, instanceID: string): boolean; /** * Create a sharded WAL manager. * * @param opt.dir - Base directory to store shard files (defaults to process.cwd()) * @param opt.format - WAL format configuration * @param opt.groupId - Group ID for sharding (defaults to generated group ID) * @param opt.coordinatorIdEnvVar - Environment variable name for storing coordinator ID (defaults to CP_SHARDED_WAL_COORDINATOR_ID) * @param opt.autoCoordinator - Whether to auto-set the coordinator ID on construction (defaults to true) */ constructor(opt: { debug?: boolean; dir?: string; format: WalFormat; groupId?: string; coordinatorIdEnvVar: string; autoCoordinator?: boolean; }); /** * Gets the unique instance ID for this ShardedWal. * * @returns The unique instance ID */ get id(): string; /** * Is this instance the coordinator? * * Coordinator status is determined from the coordinatorIdEnvVar environment variable. * The coordinator handles finalization and cleanup of shard files. * Checks dynamically to allow coordinator to be set after construction. * * @returns true if this instance is the coordinator, false otherwise */ isCoordinator(): boolean; /** * Asserts that the WAL is in 'active' state. * Throws an error if the WAL has been finalized or cleaned. * * @throws Error if WAL is not in 'active' state */ private assertActive; /** * Gets the current lifecycle state of the WAL. * * @returns Current lifecycle state: 'active', 'finalized', or 'cleaned' */ getState(): 'active' | 'finalized' | 'cleaned'; /** * Checks if the WAL has been finalized. * * @returns true if WAL is in 'finalized' state, false otherwise */ isFinalized(): boolean; /** * Checks if the WAL has been cleaned. * * @returns true if WAL is in 'cleaned' state, false otherwise */ isCleaned(): boolean; /** * Generates a filename for a shard file using a shard ID. * Both groupId and shardId are already in readable date format. * * Example with baseName "trace" and shardId "20240101-120000-000.12345.1.1": * Filename: trace.20240101-120000-000.12345.1.1.log * * @param shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format) * @returns The filename for the shard file */ getShardedFileName(shardId: string): string; /** * Generates a filename for the final merged output file. * Uses the groupId as the identifier in the final filename. * * Example with baseName "trace" and groupId "20240101-120000-000": * Filename: trace.20240101-120000-000.json * * Example with baseName "trace" and groupId "measureName": * Filename: trace.measureName.json * * @returns The filename for the final merged output file */ getFinalFilePath(): string; shard(): WriteAheadLogFile; /** Get all shard file paths matching this WAL's base name */ private shardFiles; /** Get shard file paths created by this instance */ private getCreatedShardFiles; /** * Finalize all shards by merging them into a single output file. * Recovers all records from all shards, validates no errors, and writes merged result. * Idempotent: returns early if already finalized or cleaned. * @throws Error if custom finalizer method throws */ finalize(opt?: Record): void; /** * Cleanup shard files by removing them from disk. * Coordinator-only: throws error if not coordinator to prevent race conditions. * Idempotent: returns early if already cleaned. */ cleanup(): void; get stats(): { lastRecovery: { file: string; result: RecoverResult>; }[]; state: "active" | "finalized" | "cleaned"; groupId: string; shardCount: number; isCoordinator: boolean; isFinalized: boolean; isCleaned: boolean; finalFilePath: string; shardFileCount: number; shardFiles: string[]; }; finalizeIfCoordinator(opt?: Record): void; /** * Cleanup shard files if this instance is the coordinator. * Safe to call from any process - only coordinator will execute cleanup. */ cleanupIfCoordinator(): void; }