EAI-7650: Set explicit request timeout on SeaweedFS S3 route - #800
EAI-7650: Set explicit request timeout on SeaweedFS S3 route#800nowycondro wants to merge 3 commits into
Conversation
The seaweed HTTPRoute declared no timeouts, so Envoy applied its 15s default request timeout to the S3 data path. Transfers longer than 15s were reset mid-stream, truncating objects regardless of their size. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Updates the SeaweedFS S3 HTTPRoute to explicitly set longer Gateway API timeouts so Envoy doesn’t apply its 15s default request timeout and reset long-running object transfers mid-stream.
Changes:
- Add
timeouts.requestandtimeouts.backendRequestset to30mon theseaweedHTTPRoute rule. - Document the rationale inline (duration-based timeout causing truncated objects on slow links).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
brownzebra
left a comment
There was a problem hiding this comment.
Is 15 sec -> 30 minutes really the amount to change? would 1m not be enough?
Instead of hardcoding in the template, I suggest to parametrize it into values and allow for a gitea override.
|
OK, so it is based on the whole transfer... would still be nice to have it templated so it could be tuned in the field. |
The timeout was hardcoded in the template, so a cluster hitting a different transfer profile had no way to retune it. Move it to values under s3Route.timeouts, matching the aiwb-api route convention, so it can be overridden per cluster from the gitea values repo.
|
Parametrized in be1b708 — the timeout now comes from values: s3Route:
timeouts:
request: 30m
backendRequest: 30mwith the template reading Put it under a top-level Kept the default at 30m per the transfer-duration point above. The rationale comment moved to Verified |
Summary
The
seaweedHTTPRoute declares notimeouts, so Envoy applies its 15 second default request timeout to the SeaweedFS S3 data path. Any transfer lasting longer than 15s is reset mid-stream.The limit is duration, not size, which is why it doesn't show up as a body-size setting anywhere. On a slow client link even a modest object fails.
Evidence
Measured against
app-devusing the same 26 MB object and the same presigned URL, varying only transfer speed:Failures surface as
HTTP/2 stream not closed cleanly: INTERNAL_ERROR. Note the response begins asHTTP 200and the stream resets afterwards, so clients see a truncated object rather than a clean error — a silent corruption risk for anything that doesn't verify length or checksum.Confirmed from the live Envoy config dump that the route's
timeoutfield is unset, while routes that need longer already set one explicitly (aiwb-api-routeruns at 10m/30m, AIM routes at 1800s). This route was simply left at the default.Change
Sets
requestandbackendRequeston the S3 route, defaulting to30mand read froms3Route.timeoutsin values so each cluster can retune it from its own values repo without patching the chart. Theseaweed-adminroute is left untouched.The knob sits at a top-level
s3Routerather than insideseaweed, becauseseaweedfs-seaweed.yamlwraps that block in{{- with .Values.seaweed }}and maps it 1:1 onto the Seaweed CR — a route timeout is not part of that CR. The shape mirrors the existingkgateway.aiwbapi.timeoutsconvention inaiwb-api.Test plan
helm template sources/seaweedfs-configrenders the expectedtimeoutsblockhelm lintclean; default renders30m, and--set s3Route.timeouts.request=2moverrides itkubectl apply --dry-run=serveraccepts the manifest, validating the30mduration format against the Gateway API schemaContext
This unblocks adapter artifact uploads in AIWB (EAI-7650), where users upload LoRA adapter files directly to storage through a presigned URL. Without this, those uploads fail for anyone whose connection can't finish inside 15 seconds.