Skip to content

Add large payload support#272

Open
bachuv wants to merge 7 commits intomainfrom
vabachu/large-payload
Open

Add large payload support#272
bachuv wants to merge 7 commits intomainfrom
vabachu/large-payload

Conversation

@bachuv
Copy link
Copy Markdown
Contributor

@bachuv bachuv commented Mar 23, 2026

Issue describing the changes in this PR

Adding large payload support in the Java SDK.

Pull request checklist

  • My changes do not require documentation changes
    • Otherwise: Documentation issue linked to PR
  • My changes are added to the CHANGELOG.md
  • I have added all required tests (Unit tests, E2E tests)

Additional information

Additional PR information

@bachuv bachuv requested a review from a team as a code owner March 23, 2026 05:31
Copilot AI review requested due to automatic review settings March 23, 2026 05:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds large payload support to the Durable Task Java SDK by introducing an external payload store abstraction, wiring it into client/worker/runner execution paths, and providing an Azure Blob Storage-backed implementation for Azure Functions scenarios.

Changes:

  • Introduces PayloadStore, LargePayloadOptions, and internal helpers to externalize/resolve payloads in protobuf messages.
  • Updates worker/client/orchestration runner to resolve incoming tokens and externalize outgoing large payloads; adds orchestrator response chunking.
  • Adds new azure-blob-payloads module with BlobPayloadStore + options, and wires it into the Azure Functions middleware.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
settings.gradle Registers the new :azure-blob-payloads Gradle module.
client/src/main/java/com/microsoft/durabletask/PayloadStore.java Public interface for upload/download + token recognition.
client/src/main/java/com/microsoft/durabletask/LargePayloadOptions.java Configures externalization thresholds and max externalized payload size.
client/src/main/java/com/microsoft/durabletask/PayloadHelper.java Centralizes size checks + store delegation for externalize/resolve.
client/src/main/java/com/microsoft/durabletask/PayloadInterceptionHelper.java Resolves/externalizes payload fields inside orchestration/activity protobufs.
client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcWorkerBuilder.java Adds externalized payload configuration + response chunk-size configuration.
client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcWorker.java Resolves incoming tokens, externalizes outputs, announces capability, and chunks orchestrator responses.
client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClientBuilder.java Adds externalized payload configuration for the client.
client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java Externalizes outgoing inputs/reasons and resolves tokens in returned metadata.
client/src/main/java/com/microsoft/durabletask/OrchestrationRunner.java Adds overloads to run orchestrations with externalized payload support.
client/src/test/java/com/microsoft/durabletask/PayloadHelperTest.java Unit tests for thresholding, max cap behavior, and resolve/externalize round trips.
client/src/test/java/com/microsoft/durabletask/PayloadInterceptionHelperTest.java Unit tests verifying request/response interception resolves/externalizes expected fields.
client/src/test/java/com/microsoft/durabletask/LargePayloadOptionsTest.java Unit tests for defaults and validation behavior.
client/src/test/java/com/microsoft/durabletask/OrchestrationRunnerPayloadTest.java Tests runner load+run behavior with/without a store.
client/src/test/java/com/microsoft/durabletask/DurableTaskGrpcWorkerBuilderTest.java Tests chunk-size validation and externalized payload builder configuration.
client/src/test/java/com/microsoft/durabletask/LargePayloadIntegrationTests.java End-to-end integration tests for externalization + autochunk behavior.
client/build.gradle Makes test Java executable selection Windows-aware.
azurefunctions/src/main/java/.../OrchestrationMiddleware.java Initializes a blob-backed payload store from env vars and passes it to the runner.
azurefunctions/build.gradle Adds dependency on the new :azure-blob-payloads module.
azure-blob-payloads/build.gradle New module build + publish/sign/spotbugs configuration.
azure-blob-payloads/src/main/java/.../BlobPayloadStoreOptions.java Config object for blob-based payload storage.
azure-blob-payloads/src/main/java/.../BlobPayloadStore.java Azure Blob-backed PayloadStore implementation with optional gzip.
azure-blob-payloads/src/main/java/.../AzureBlobPayloadsExtensions.java Convenience methods to configure builders with blob payload storage.
azure-blob-payloads/src/test/java/.../BlobPayloadStoreOptionsTest.java Unit tests for options validation and defaults.
azure-blob-payloads/spotbugs-exclude.xml SpotBugs exclusions for exposed Azure SDK client objects in options.

Copy link
Copy Markdown
Member

@YunchuWang YunchuWang left a comment

Choose a reason for hiding this comment

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

Code Review: Large Payload Support

Good overall design — the PayloadStore abstraction, PayloadHelper threshold logic, and PayloadInterceptionHelper protobuf interception are well-structured. The response chunking implementation is solid. However, I found several issues that need attention.

Summary of Findings

Critical:

  1. OrchestrationMiddleware silently enables blob storage for ALL Azure Functions apps (falls back to AzureWebJobsStorage)
  2. OrchestrationMiddleware hardcodes BlobPayloadStore — violates the PayloadStore abstraction

Medium (Performance):
3. BlobPayloadStore.upload() makes 2 HTTP calls for compressed uploads (upload + setHttpHeaders)
4. BlobPayloadStore.download() makes 2 HTTP calls (downloadStream + getProperties)
5. PayloadHelper.maybeExternalize() allocates full UTF-8 byte array just to check size

Low / Design:
6. BlobPayloadStore.extractBlobName() ignores container name from token
7. PayloadStore interface has no delete() — externalized payloads accumulate forever
8. PayloadInterceptionHelperfield.isInitialized() is always true in proto3
9. BlobPayloadStore constructor makes network call (ensureContainerExists)

@bachuv bachuv requested a review from YunchuWang March 26, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants