Skip to content

VE-21573: poll HEAD after PUT upload before signalling success#617

Merged
mattdizon merged 4 commits into
masterfrom
ve-21573-upload-head-check-before-create-tdo
Jul 20, 2026
Merged

VE-21573: poll HEAD after PUT upload before signalling success#617
mattdizon merged 4 commits into
masterfrom
ve-21573-upload-head-check-before-create-tdo

Conversation

@mattdizon

@mattdizon mattdizon commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • After a PUT to a signed S3 URL completes, the file may not be immediately readable due to S3 eventual consistency
  • Added a pollForFileAvailability function in uploadFilesChannel.js that issues a HEAD request to descriptor.getUrl after PUT success
  • Uses exponential backoff (1s → 2s → 4s → 8s → 16s) with up to 5 retries before proceeding anyway
  • createTDOWithAsset is now only called after the HEAD confirms the file is readable, eliminating the race condition
  • Falls back safely: if descriptor.getUrl is absent, emits success immediately (existing behaviour)

Test plan

  • Start Storybook (npm run start:storybook in packages/veritone-widgets)
  • Open a FilePicker/DataPicker story with upload enabled and a valid API token
  • Upload a file and open DevTools → Network tab (filter XHR)
  • Confirm request order: getSignedWritableUrl → PUT to signed URL → HEAD to getUrlcreateTDOWithAsset
  • Block the HEAD URL in DevTools to confirm retries fire with exponential backoff, then createTDOWithAsset proceeds after max retries

Closes VE-21573

🤖 Generated with Claude Code

Matthew Dizon and others added 4 commits June 23, 2026 21:29
After a PUT to a signed S3 URL completes, the object may not be
immediately readable due to S3 eventual consistency. This adds a HEAD
request to the getUrl after PUT success, with exponential backoff
retries (up to 5), so that createTDOWithAsset is only called once the
file is confirmed readable — eliminating the race condition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers: PUT success + HEAD confirms readability, exponential backoff
retries, max retries exhausted (proceeds anyway), PUT failure skips
HEAD, abort (status 0), multi-file END only after all lifecycles
complete, and requestMap population/cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add eslint-env node,jest so `global` is recognised
- Drop unused `channel` binding in requestMap test
- Remove spurious `async` on test with no await

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
forEach creates all PUT XHRs before any callbacks fire, so
instances[1] is PUT b (not HEAD a). HEAD XHRs only appear after
their PUT completes. Also interleave takes with puts to avoid
overflowing the sliding(2) channel buffer in sync test code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@stefanminkov stefanminkov left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

👍

@mattdizon
mattdizon merged commit a8dc258 into master Jul 20, 2026
7 checks passed
@mattdizon
mattdizon deleted the ve-21573-upload-head-check-before-create-tdo branch July 20, 2026 18:11
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.

2 participants