Skip to content

[Storage] Photon Proof-of-Concept#4796

Draft
vincenttran-msft wants to merge 3 commits into
Azure:mainfrom
vincenttran-msft:vincenttran/photon_wip
Draft

[Storage] Photon Proof-of-Concept#4796
vincenttran-msft wants to merge 3 commits into
Azure:mainfrom
vincenttran-msft:vincenttran/photon_wip

Conversation

@vincenttran-msft

Copy link
Copy Markdown
Member

Prototype end-to-end support for receiving the flat blob listing as an Apache Arrow IPC stream, decoding it into the existing ListBlobsResponse model. This proves correctness of the wire format and decode path; it is not yet a performance win (see "What's left").

What this covers

  • New listing method BlobContainerClient::list_blob_flat_segment_apache_arrow(accept, options) that exposes an accept: ListBlobsAcceptFormat enum (Arrow / Auto / Xml). Arrow/Auto request application/vnd.apache.arrow.stream,application/xml; Xml requests application/xml. In actuality, we would just implement this change to list_blobs and make it optional.
  • Response content negotiation — the pager closure branches on the response Content-Type (server-dictated, not the request Accept), so both an Arrow stream and an XML fallback are handled correctly.
  • Arrow decoder (src/arrow_decode.rs) — decodes an Arrow IPC stream into ListBlobsResponse: per-row BlobItem/BlobProperties for a subset of columns (name, timestamps, blob type, etag, content length/type, Content-MD5, access tier, lease state/status, server-encrypted) plus NextMarker from schema metadata.
  • Dependenciesarrow-array, arrow-ipc, arrow-schema (59.1.0).
  • Teststest_list_blobs_observe_raw dumps the raw wire response (via Auto). Existing list_blobs tests are temporarily pointed at the new method with Xml to confirm the original XML path still works.

What's left

  • Direct Arrow decode (the actual perf win). Today the Arrow branch decodes then re-encodes to XML so the existing XmlFormat pipeline can re-parse it downstream - a full round-trip that is slower than XML. Production ready code needs a real ArrowFormat that decodes Arrow straight into the model with no XML round-trip.
  • Configurable Accept via options/client (deferred) rather than a required positional argument.
  • Full field coverage — envelope fields (container name, prefix, marker, max results, service endpoint) and map-typed columns (tags, metadata) are not yet mapped from Arrow.
  • Codegen / TypeSpec fixes — (1) all edits live in generated/ and will be overwritten by tsp-client update; the emitter must learn to produce this. (2) ListBlobsAcceptFormat::{Arrow, Auto} map to the same Accept string, making Auto unreachable in FromStr (currently suppressed).
  • Revert the temporary test diversion back to list_blobs, and add proper Arrow + XML recordings.
  • How to smooth over the introduction of the arrow format given we already are locked to the current response:
    Result<Pager<ListBlobsResponse, XmlFormat>>

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions github-actions Bot added the Storage Storage Service (Queues, Blobs, Files) label Jul 17, 2026
#[tracing::function("Storage.Blob.BlobContainerClient.listBlobFlatSegmentApacheArrow")]
pub fn list_blob_flat_segment_apache_arrow(
&self,
accept: ListBlobsAcceptFormat,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would make this an option bag option, but made it a parameter for now just for ease of refactoring between different accept values since most of the time we don't even use an optioned API call

Comment on lines +791 to +808
let is_arrow = headers
.get_optional_str(&azure_core::http::headers::CONTENT_TYPE)
.is_some_and(|content_type| {
content_type.contains("application/vnd.apache.arrow.stream")
});
// Condition on whether we got back XML or arrow (since you can request arrow but may hit XML fallback)
let (body, next_marker) = if is_arrow {
// PROOF-OF-CONCEPT ONLY: This currently decodes arrow then re-encoding to XML to make the return type happy.
// (re-decoded later in `into_model()`). Therefore this adds a full round-trip, negating the benefits of adding arrow support.
// Discussion point: How to smooth over the return type issue (Result<Pager<ListBlobsResponse, XmlFormat>>).
let model = crate::arrow_decode::decode_arrow_list_blobs(&body)?;
let next_marker = model.next_marker.clone();
(xml::to_xml(&model)?, next_marker)
} else {
let page: BlobContainerClientListBlobFlatSegmentApacheArrowPage =
xml::from_xml(&body)?;
(body.into(), page.next_marker)
};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the conditional logic section

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Storage Storage Service (Queues, Blobs, Files)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant