Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:ArroyoSystems Arroyo Sink V2 Open File

From Leeroopedia
Revision as of 14:28, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/ArroyoSystems_Arroyo_Sink_V2_Open_File.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Knowledge Sources
Domains Streaming, Connectors, File_Systems
Last Updated 2026-02-08 08:00 GMT

Overview

Implements the OpenFile state machine that manages the complete lifecycle of a single output file in the V2 filesystem sink, from initial writing through multipart upload orchestration, checkpointing, recovery, and finalization.

Description

The OpenFile<BBW> struct is the central file management abstraction in the V2 sink. It encapsulates a state machine (OpenFileState) that tracks the file through its entire lifecycle:

States:

  • New - File has a writer but no multipart upload has been started. Data is buffered locally. Transitions to MultipartStarting when the buffer reaches minimum_multipart_size or target_part_size_bytes.
  • MultipartStarting - A multipart upload initialization request has been sent. Optionally tracks then_close if the file needs to close before the init completes.
  • MultipartStarted - Multipart upload is active. Parts are flushed when the buffer reaches target_part_size_bytes. Each part is tracked as a Part struct with index and optional content ID.
  • Recovering - Restored from checkpoint with a known multipart ID, completed parts, and trailing bytes that still need uploading.
  • ClosingMulti - Writer has been closed; all data converted to parts. Waiting for in-flight part uploads to complete.
  • ClosingSingle - Writer has been closed and all data fits in a single file (no multipart). Bytes are held in memory.
  • Finishing - Multipart finalization or single file upload has been initiated.
  • Closed - File is fully written and finalized.
  • Failed - Terminal error state.

Key Operations:

  • add_batch - Writes a batch to the underlying BatchBufferingWriter and triggers maybe_flush to check if a new part upload should start.
  • close - Transitions the file to a closing state. For multipart files, the writer's final bytes become the last upload parts. For small files, the bytes are held for single-file upload.
  • handle_event - Processes asynchronous upload results (MultipartInitialized, PartFinished, SingleFileFinished, MultipartFinalized) and transitions the state machine accordingly.
  • prepare_for_commit - Determines the commit strategy: Serializable (multipart files already uploaded), UploadThenSerialize (single files needing upload in PerOperator mode), or LocalCommit (single files in PerSubtask mode).
  • finalize - Initiates the actual multipart close or single-file upload.
  • as_checkpoint - Serializes the current file state for checkpoint recovery.
  • from_checkpoint / from_commit - Reconstructs an OpenFile from checkpoint or commit data for recovery.

Supporting Types:

  • PendingSingleFile - Minimal type holding a path, bytes, and metadata for a single-file upload that will be finalized during the commit phase.
  • CommitPreparation - Enum describing the three possible ways a file can enter the commit pipeline.
  • Part - Tracks a multipart upload part index and its completion status.

The module handles object store constraints such as same-part-size requirements (e.g., S3) by splitting oversized final parts using split_into_parts.

Usage

Used exclusively by FileSystemSinkV2 to manage individual output files. Each open partition maps to one OpenFile instance.

Code Reference

Source Location

Signature

pub struct OpenFile<BBW: BatchBufferingWriter + 'static> {
    pub path: Arc<Path>,
    pub stats: MultiPartWriterStats,
    pub logger: FsEventLogger,
    pub state: OpenFileState<BBW>,
    pub target_part_size_bytes: usize,
    pub minimum_multipart_size: usize,
    pub storage_provider: Arc<StorageProvider>,
}

pub enum OpenFileState<BBW: BatchBufferingWriter> {
    New { writer: BBW },
    MultipartStarting { writer: BBW, then_close: bool },
    MultipartStarted { writer: BBW, multipart_id: Arc<MultipartId>, parts: Vec<Part> },
    Recovering { multipart_id: Arc<MultipartId>, parts: Vec<Part>, trailing_bytes: Bytes, ... },
    ClosingMulti { multipart_id: Arc<MultipartId>, parts: Vec<Part>, ... },
    ClosingSingle { bytes: Bytes, iceberg_metadata: Option<IcebergFileMetadata> },
    Finishing { iceberg_metadata: Option<IcebergFileMetadata>, total_size: usize },
    Closed { iceberg_metadata: Option<IcebergFileMetadata>, total_size: usize },
    Failed,
}

pub enum CommitPreparation {
    Serializable(FileToCommit),
    UploadThenSerialize(BoxFuture<'static, DataflowResult<FileToCommit>>),
    LocalCommit(PendingSingleFile),
}

pub struct PendingSingleFile { ... }

impl<BBW: BatchBufferingWriter + 'static> OpenFile<BBW> {
    pub fn new(path: Arc<Path>, writer: BBW, ...) -> Self;
    pub fn from_checkpoint(file: InProgressFile, ...) -> DataflowResult<Self>;
    pub fn from_commit(file: FileToCommit, ...) -> DataflowResult<Self>;
    pub fn is_writable(&self) -> bool;
    pub fn ready_to_finalize(&self) -> bool;
    pub fn add_batch(&mut self, batch: &RecordBatch) -> DataflowResult<Option<UploadFuture>>;
    pub fn handle_event(&mut self, event: FsResponseData) -> DataflowResult<Vec<UploadFuture>>;
    pub fn close(&mut self) -> DataflowResult<Vec<UploadFuture>>;
    pub fn prepare_for_commit(self, strategy: CommitStrategy) -> DataflowResult<CommitPreparation>;
    pub fn finalize(&mut self) -> DataflowResult<UploadFuture>;
    pub fn as_checkpoint(&mut self) -> DataflowResult<InProgressFile>;
    pub fn metadata_for_closed(self) -> DataflowResult<(usize, Option<IcebergFileMetadata>)>;
}

Import

use arroyo_connectors::filesystem::sink::v2::open_file::{
    OpenFile, OpenFileState, CommitPreparation, PendingSingleFile,
};

I/O Contract

Inputs

Name Type Required Description
path Arc<Path> Yes Object store path for the file
writer BBW (BatchBufferingWriter) Yes Format-specific buffered writer
batch RecordBatch Yes Arrow record batch to write to the file
event FsResponseData Yes Async upload event (init, part finish, file finish, finalize)
InProgressFile InProgressFile No Checkpoint data for recovery
FileToCommit FileToCommit No Pre-commit data for recovery during commit phase

Outputs

Name Type Description
UploadFuture UploadFuture Asynchronous upload operations (multipart init, part upload, finalize, single file put)
InProgressFile InProgressFile Serializable checkpoint state for the file
FileToCommit FileToCommit Serializable pre-commit data for the commit phase
CommitPreparation CommitPreparation Strategy for how this file should enter the commit pipeline

Usage Examples

// Create a new open file
let mut file = OpenFile::new(
    path,
    parquet_writer,
    logger,
    storage_provider,
    representative_timestamp,
    &config,
);

// Write batches
if let Some(upload_future) = file.add_batch(&batch)? {
    pending_uploads.push(upload_future);
}

// Close the file when rolling policy triggers
let close_futures = file.close()?;

// After all uploads complete, prepare for commit
let preparation = file.prepare_for_commit(CommitStrategy::PerOperator)?;

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment