Skip to content

Make GCS deletes idempotent and raise delete_many timeout#139

Merged
ericmj merged 1 commit into
mainfrom
gs-delete-fixes
Jul 9, 2026
Merged

Make GCS deletes idempotent and raise delete_many timeout#139
ericmj merged 1 commit into
mainfrom
gs-delete-fixes

Conversation

@ericmj

@ericmj ericmj commented Jul 8, 2026

Copy link
Copy Markdown
Member

Fixes three Sentry crashes in docs upload processing, all in Hexdocs.Store.GS:

  • 7497335792: delete/2 pattern-matched on {:ok, 204, ...}, but GCS returns 404 when the object is already gone — which happens when two uploads of the same package run concurrently and both try to delete the package-level docs_config.js. Deletes now treat 404 as success.
  • 7599887867 and 7598306452 (same failure reported from the task and from the Broadway processor): delete_many/2 ran its Task.async_stream with a 10s per-task timeout, but Hexdocs.HTTP.retry can spend 8s in backoff sleeps alone, plus up to 30s per attempt, so a single slow or retried GCS delete crashed the whole upload. The timeout is now 60s, matching upload_new_files/1 in Hexdocs.Bucket.

Crashed uploads self-healed via SQS redelivery, so the impact was limited to delayed docs publishing.

GCS returns 404 when an object was already deleted, for example by a
concurrent upload of the same package deleting the same unversioned
files. Treat 404 as success in Hexdocs.Store.GS.delete/2 instead of
crashing the whole upload with a MatchError.

Also raise the delete_many Task.async_stream timeout from 10s to 60s,
matching upload_new_files: a single retried GCS request can spend 8s
in backoff sleeps alone, so a slow delete could exceed the 10s task
timeout and crash the upload.
@ericmj ericmj marked this pull request as ready for review July 9, 2026 00:22
@ericmj ericmj merged commit 2113ab8 into main Jul 9, 2026
8 checks passed
@ericmj ericmj deleted the gs-delete-fixes branch July 9, 2026 23:06
ericmj added a commit that referenced this pull request Jul 9, 2026
PR #139 added test/hexdocs/store/gs_test.exs, which uses Bandit and
Plug.Conn for a mock GCS server, while PR #140 removed the bandit
dependency along with the HTTP serving layer. Each PR passed CI against
its own base, but together they broke compilation of the test suite on
main.

Keep the app itself a pure background pipeline by re-adding bandit only
for the test environment.
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.

1 participant