Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions docs/packages/aws-lambda.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ const site = await deploySite({

const handle = await renderToLambda({
siteHandle: site,
planProtocol: "v2",
bucketName: site.bucketName,
stateMachineArn: "arn:aws:states:us-east-1:123456789012:stateMachine:hyperframes-render",
config: {
Expand All @@ -88,10 +87,17 @@ const progress = await getRenderProgress({ executionArn: handle.executionArn });
console.log(progress.status, progress.overallProgress, progress.costs.displayCost);
```

Plan v2 is recommended for new integrations because workers fetch
manifest-selected content-addressed artifacts. For backwards compatibility,
omitting `planProtocol` still selects v1; existing callers do not change
behavior until they opt in.
Plan v2 is the default because workers fetch manifest-selected
content-addressed artifacts. The SDK sends explicit v2 when `planProtocol` is
omitted. Deprecated v1 compatibility remains available by passing
`planProtocol: "v1"`.

<Warning>
For an existing installation, pause new renders and drain active Step
Functions executions. Redeploy the Lambda handler and SAM/CDK state machine
from the same package version before upgrading the application SDK. Older
infrastructure may default omission to v1 or lack v2 support.
</Warning>

`renderToLambda()` validates the distributed render config before starting the Step Functions execution, so invalid dimensions, formats, chunk sizes, or payload sizes fail synchronously.

Expand Down
16 changes: 11 additions & 5 deletions docs/packages/gcp-cloud-run.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ import { getRenderProgress, renderToCloudRun } from "@hyperframes/gcp-cloud-run/

const handle = await renderToCloudRun({
projectDir: "./my-composition",
planProtocol: "v2",
config: { fps: 30, width: 1920, height: 1080, format: "mp4" },
bucketName: "hyperframes-render-my-project",
projectId: "my-project",
Expand All @@ -97,10 +96,17 @@ while (progress.status === "running") {
console.log(progress.status, progress.outputFile, progress.costs.displayCost);
```

Plan v2 is recommended for new integrations because workers fetch
manifest-selected content-addressed artifacts. For backwards compatibility,
omitting `planProtocol` still selects v1; existing callers do not change
behavior until they opt in.
Plan v2 is the default because workers fetch manifest-selected
content-addressed artifacts. The SDK sends explicit v2 when `planProtocol` is
omitted. Deprecated v1 compatibility remains available by passing
`planProtocol: "v1"`.

<Warning>
For an existing installation, pause new renders and drain active workflow
executions. Redeploy the Cloud Run image and Cloud Workflows definition from
the same package version before upgrading the application SDK. Older
workflows may default omission to v1 or lack v2 support.
</Warning>

Pass `projectDir` for one-shot uploads, or call `deploySite()` separately and reuse the returned site handle across many renders.

Expand Down
32 changes: 22 additions & 10 deletions examples/aws-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ aws stepfunctions start-execution \
"ProjectS3Uri": "s3://${RENDER_BUCKET}/projects/my-project.tar.gz",
"PlanOutputS3Prefix": "s3://${RENDER_BUCKET}/renders/$(date +%s)/",
"OutputS3Uri": "s3://${RENDER_BUCKET}/output.mp4",
"PlanProtocol": "v2",
"Config": {
"fps": 30,
"width": 1920,
Expand All @@ -92,10 +91,20 @@ EOF

The Step Functions execution kicks off Plan, fans out RenderChunk via
the Map state, and finally Assemble. Final mp4 lands at `OutputS3Uri`.
Plan v2 is recommended for new integrations. `PlanProtocol` may be `"v1"` or
`"v2"`; absent still defaults to v1 for backwards compatibility. V2 uses
separate manifest and content-addressed artifact locators throughout the
workflow and never places a v2 object in `PlanS3Uri`.
Plan v2 is the default when `PlanProtocol` is absent. V2 uses separate
manifest and content-addressed artifact locators throughout the workflow and
never places a v2 object in `PlanS3Uri`. The deprecated v1 transport remains
available by sending `"PlanProtocol": "v1"` explicitly.

### Upgrading an existing stack

Pause new renders and let active Step Functions executions drain before the
upgrade. Redeploy the Lambda handler and this state machine (or the matching
CDK construct) from the same package version before upgrading the application
that calls `renderToLambda`. The new SDK sends explicit v2 by default, while
older infrastructure may default omission to v1 or lack v2 support. Keep
passing `planProtocol: "v1"` until the infrastructure redeploy completes if
you need a staged migration.

## Local invocation

Expand All @@ -112,10 +121,13 @@ sam validate
sam local invoke RenderFunction --event sample-events/plan.json
```

The `sample-events/` directory ships small JSON payloads for each of the
three actions. They reference fake S3 URIs — useful for sanity-checking
the handler's dispatch logic; not for full end-to-end testing (real S3
calls require credentials and a project zip to actually exist).
The `sample-events/` directory ships three tiers for each action:
`*.json` demonstrates default v2 with `PlanProtocol` omitted, `*-v1.json`
demonstrates deprecated explicit-v1 compatibility, and `*-v2.json`
demonstrates callers that stamp v2 explicitly. They reference fake S3 URIs —
useful for sanity-checking the handler's dispatch logic; not for full
end-to-end testing (real S3 calls require credentials and a project zip to
actually exist).

## End-to-end smoke + benchmark

Expand All @@ -124,7 +136,7 @@ the architecture works on a deployed Lambda — use the local smoke
script:

```bash
# Defaults use the fixture's meta.json minPsnr (30 dB for mp4-h264-sdr).
# Defaults use Plan v2 and the fixture's meta.json minPsnr (30 dB for mp4-h264-sdr).
./scripts/smoke.sh

# Customised:
Expand Down
12 changes: 12 additions & 0 deletions examples/aws-lambda/sample-events/assemble-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Action": "assemble",
"PlanProtocol": "v1",
"PlanS3Uri": "s3://example-bucket/renders/sample/plan.tar.gz",
"ChunkS3Uris": [
"s3://example-bucket/renders/sample/chunks/0000.mp4",
"s3://example-bucket/renders/sample/chunks/0001.mp4"
],
"AudioS3Uri": null,
"OutputS3Uri": "s3://example-bucket/renders/sample/output.mp4",
"Format": "mp4"
}
4 changes: 3 additions & 1 deletion examples/aws-lambda/sample-events/assemble.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"Action": "assemble",
"PlanS3Uri": "s3://example-bucket/renders/sample/plan.tar.gz",
"PlanV2ManifestS3Uri": "s3://example-bucket/renders/sample/v2/manifest.json",
"PlanV2ArtifactS3Prefix": "s3://example-bucket/renders/sample/v2/artifacts/sha256",
"PlanHash": "0000000000000000000000000000000000000000000000000000000000000000",
"ChunkS3Uris": [
"s3://example-bucket/renders/sample/chunks/0000.mp4",
"s3://example-bucket/renders/sample/chunks/0001.mp4",
Expand Down
15 changes: 15 additions & 0 deletions examples/aws-lambda/sample-events/plan-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Action": "plan",
"PlanProtocol": "v1",
"ProjectS3Uri": "s3://example-bucket/projects/sample.tar.gz",
"PlanOutputS3Prefix": "s3://example-bucket/renders/sample/",
"Config": {
"fps": 30,
"width": 1920,
"height": 1080,
"format": "mp4",
"chunkSize": 240,
"maxParallelChunks": 8,
"runtimeCap": "lambda"
}
}
2 changes: 1 addition & 1 deletion examples/aws-lambda/sample-events/plan.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Action": "plan",
"ProjectS3Uri": "s3://example-bucket/projects/sample-composition.tar.gz",
"ProjectS3Uri": "s3://example-bucket/projects/sample.tar.gz",
"PlanOutputS3Prefix": "s3://example-bucket/renders/sample/",
"Config": {
"fps": 30,
Expand Down
9 changes: 9 additions & 0 deletions examples/aws-lambda/sample-events/render-chunk-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Action": "renderChunk",
"PlanProtocol": "v1",
"PlanS3Uri": "s3://example-bucket/renders/sample/plan.tar.gz",
"PlanHash": "0000000000000000000000000000000000000000000000000000000000000000",
"ChunkIndex": 0,
"ChunkOutputS3Prefix": "s3://example-bucket/renders/sample/",
"Format": "mp4"
}
3 changes: 2 additions & 1 deletion examples/aws-lambda/sample-events/render-chunk.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"Action": "renderChunk",
"PlanS3Uri": "s3://example-bucket/renders/sample/plan.tar.gz",
"PlanV2ManifestS3Uri": "s3://example-bucket/renders/sample/v2/manifest.json",
"PlanV2ArtifactS3Prefix": "s3://example-bucket/renders/sample/v2/artifacts/sha256",
"PlanHash": "0000000000000000000000000000000000000000000000000000000000000000",
"ChunkIndex": 0,
"ChunkOutputS3Prefix": "s3://example-bucket/renders/sample/",
Expand Down
6 changes: 3 additions & 3 deletions examples/aws-lambda/scripts/smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# --region <region> (default: $AWS_REGION or us-east-1)
# --profile <name> (default: $AWS_PROFILE, otherwise the AWS
# default profile resolution chain)
# --plan-protocol <v1|v2|both> (default: v1)
# --plan-protocol <v1|v2|both> (default: v2)
# --keep-stack (skip `sam delete` at the end)
# --skip-build (skip the ZIP rebuild; use the existing one)
#
Expand Down Expand Up @@ -82,7 +82,7 @@ SMOKE_RUN_ID="${HYPERFRAMES_SMOKE_RUN_ID:-$(hf_new_smoke_run_id)}"
STACK_NAME="${STACK_NAME:-hyperframes-lambda-smoke-${SMOKE_RUN_ID}}"
AWS_REGION="${AWS_REGION:-us-east-1}"
AWS_PROFILE="${AWS_PROFILE:-}"
PLAN_PROTOCOL="${PLAN_PROTOCOL:-v1}"
PLAN_PROTOCOL="${PLAN_PROTOCOL:-v2}"
KEEP_STACK="false"
SKIP_BUILD="false"
REQUIRE_ENCODED_SHA_EQUAL="${REQUIRE_ENCODED_SHA_EQUAL:-false}"
Expand Down Expand Up @@ -110,7 +110,7 @@ Flags:
--stack-name <name> SAM stack name (default: hyperframes-lambda-smoke-<unique-run-id>)
--region <region> AWS region (default: $AWS_REGION or us-east-1)
--profile <name> AWS profile (default: $AWS_PROFILE)
--plan-protocol <v1|v2|both> plan transport(s) to compare (default: v1)
--plan-protocol <v1|v2|both> plan transport(s) to compare (default: v2)
--reserved-concurrency <N> Lambda Map MaxConcurrency cap (default: 16)
--keep-stack skip `sam delete` at the end (manual teardown later)
--require-encoded-sha-equal also gate byte-identical encoded MP4 output
Expand Down
7 changes: 5 additions & 2 deletions examples/aws-lambda/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,12 @@ Resources:
- Variable: $.PlanProtocol
IsPresent: true
Next: UnsupportedPlanProtocol
Default: Plan
Default: PlanV2

UnsupportedPlanProtocol:
Type: Fail
Error: PLAN_PROTOCOL_UNSUPPORTED
Cause: PlanProtocol must be "v1", "v2", or absent (defaults to v1).
Cause: PlanProtocol must be "v1", "v2", or absent (defaults to v2).

Plan:
Type: Task
Expand All @@ -236,6 +236,7 @@ Resources:
FunctionName: !GetAtt RenderFunction.Arn
Payload:
Action: plan
PlanProtocol: v1
ProjectS3Uri.$: "$.ProjectS3Uri"
PlanOutputS3Prefix.$: "$.PlanOutputS3Prefix"
Config.$: "$.Config"
Expand Down Expand Up @@ -391,6 +392,7 @@ Resources:
FunctionName: !GetAtt RenderFunction.Arn
Payload:
Action: renderChunk
PlanProtocol: v1
ChunkIndex.$: "$.ChunkIndex"
PlanS3Uri.$: "$.PlanS3Uri"
PlanHash.$: "$.PlanHash"
Expand Down Expand Up @@ -427,6 +429,7 @@ Resources:
FunctionName: !GetAtt RenderFunction.Arn
Payload:
Action: assemble
PlanProtocol: v1
PlanS3Uri.$: "$.Plan.PlanS3Uri"
ChunkS3Uris.$: "$.Chunks[*].ChunkS3Uri"
AudioS3Uri.$: "$.Plan.AudioS3Uri"
Expand Down
30 changes: 21 additions & 9 deletions examples/gcp-cloud-run/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ Cloud Workflows adapter for HyperFrames distributed rendering.

```text
scripts/smoke.sh Owner-isolated real-GCP deploy, render, parity, cleanup
sample-events/ v1 and v2 handler request examples
sample-events/ Default-v2, explicit-v1, and explicit-v2 request examples
```

The Terraform module and Cloud Workflows definition live in
`packages/gcp-cloud-run/terraform/`.

## Protocol rollout

The workflow defaults to plan protocol v1 when `PlanProtocol` is absent. V2 is
accepted only when the caller explicitly sends `PlanProtocol: "v2"`.
The workflow defaults to Plan v2 when `PlanProtocol` is absent. Deprecated v1
compatibility remains available only when the caller explicitly sends
`PlanProtocol: "v1"`.

V1 and v2 use disjoint plan locators:

Expand All @@ -26,9 +27,15 @@ V1 and v2 use disjoint plan locators:

The workflow validates that the plan response matches the selected protocol
before starting chunk fan-out. It never silently falls back from v2 to v1.
Deploy the v2 workflow only with a Cloud Run image whose handler implements
the matching v2 request/response contract. An older v1-only handler will keep
serving default v1 requests, but explicit v2 smoke executions will fail closed.
Deploy the workflow only with a Cloud Run image whose handler implements the
matching v2 request/response contract.

For an existing installation, pause new renders and drain active workflow
executions. Redeploy the Cloud Run image and workflow from the same package
version before upgrading the application SDK. The new SDK sends explicit v2;
older workflows may still default omission to v1 or lack v2 support. Keep
passing `planProtocol: "v1"` until the infrastructure redeploy completes if
you need a staged migration.

## Prerequisites

Expand All @@ -40,7 +47,7 @@ serving default v1 requests, but explicit v2 smoke executions will fail closed.

## Run the smoke

V1 remains the safe default:
Plan v2 is the normal smoke path:

```bash
./scripts/smoke.sh \
Expand Down Expand Up @@ -120,12 +127,17 @@ old invocation's state or image implicitly.
The sample events mirror the request bodies sent by Cloud Workflows:

```bash
# V1
# Default v2 (PlanProtocol omitted)
curl -sX POST localhost:8080/ \
-H 'content-type: application/json' \
--data @sample-events/plan.json | jq .

# Explicit v2
# Deprecated explicit v1 compatibility
curl -sX POST localhost:8080/ \
-H 'content-type: application/json' \
--data @sample-events/plan-v1.json | jq .

# Explicit v2 for callers that always stamp the protocol
curl -sX POST localhost:8080/ \
-H 'content-type: application/json' \
--data @sample-events/plan-v2.json | jq .
Expand Down
12 changes: 12 additions & 0 deletions examples/gcp-cloud-run/sample-events/assemble-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Action": "assemble",
"PlanProtocol": "v1",
"PlanGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/plan.tar.gz",
"ChunkGcsUris": [
"gs://hyperframes-render-PROJECT/renders/hf-render-demo/chunks/0000.mp4",
"gs://hyperframes-render-PROJECT/renders/hf-render-demo/chunks/0001.mp4"
],
"AudioGcsUri": null,
"OutputGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/output.mp4",
"Format": "mp4"
}
5 changes: 3 additions & 2 deletions examples/gcp-cloud-run/sample-events/assemble.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"Action": "assemble",
"PlanProtocol": "v1",
"PlanGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/plan.tar.gz",
"PlanV2ManifestGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/v2/manifest.json",
"PlanV2ArtifactGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/v2/artifacts/sha256",
"PlanHash": "REPLACE_WITH_PLAN_HASH",
"ChunkGcsUris": [
"gs://hyperframes-render-PROJECT/renders/hf-render-demo/chunks/0000.mp4",
"gs://hyperframes-render-PROJECT/renders/hf-render-demo/chunks/0001.mp4"
Expand Down
7 changes: 7 additions & 0 deletions examples/gcp-cloud-run/sample-events/plan-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Action": "plan",
"PlanProtocol": "v1",
"ProjectGcsUri": "gs://hyperframes-render-PROJECT/sites/abc123/project.tar.gz",
"PlanOutputGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/",
"Config": { "fps": 30, "width": 1920, "height": 1080, "format": "mp4" }
}
1 change: 0 additions & 1 deletion examples/gcp-cloud-run/sample-events/plan.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"Action": "plan",
"PlanProtocol": "v1",
"ProjectGcsUri": "gs://hyperframes-render-PROJECT/sites/abc123/project.tar.gz",
"PlanOutputGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/",
"Config": { "fps": 30, "width": 1920, "height": 1080, "format": "mp4" }
Expand Down
9 changes: 9 additions & 0 deletions examples/gcp-cloud-run/sample-events/render-chunk-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Action": "renderChunk",
"PlanProtocol": "v1",
"PlanGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/plan.tar.gz",
"PlanHash": "REPLACE_WITH_PLAN_HASH",
"ChunkIndex": 0,
"ChunkOutputGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/",
"Format": "mp4"
}
4 changes: 2 additions & 2 deletions examples/gcp-cloud-run/sample-events/render-chunk.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Action": "renderChunk",
"PlanProtocol": "v1",
"PlanGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/plan.tar.gz",
"PlanV2ManifestGcsUri": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/v2/manifest.json",
"PlanV2ArtifactGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/v2/artifacts/sha256",
"PlanHash": "REPLACE_WITH_PLAN_HASH",
"ChunkIndex": 0,
"ChunkOutputGcsPrefix": "gs://hyperframes-render-PROJECT/renders/hf-render-demo/",
Expand Down
Loading
Loading