Skip to content

feat(storage): atomic setIfAbsent primitive (client)#119

Draft
Zmatarasso wants to merge 1 commit into
masterfrom
feat/storage-set-if-absent
Draft

feat(storage): atomic setIfAbsent primitive (client)#119
Zmatarasso wants to merge 1 commit into
masterfrom
feat/storage-set-if-absent

Conversation

@Zmatarasso

Copy link
Copy Markdown
Contributor

Summary

Adds a race-free "write only if the key is not already set" primitive to plugin storage — the client half of a cross-repo change (platform companion PR in envoy-web).

  • storage.setIfAbsent(key, value, { ttlSeconds? }) + pipeline set_if_absent command.
  • Resolves to the stored item on a win, or { value: undefined } when the key already existed (claim lost) — same convention as get-miss / setUnique-exhaustion, so no new result shape.
  • Additive and inert until the platform understands the set_if_absent action.

Why

Some integrations provision from two concurrent paths for the same entity — e.g. an event webhook and an app-extension render — that can run at the same instant and on different pods. Both do get → (missing) → create, and the idempotency record is only written after the external calls, so both see "missing" and both create (duplicate external records). This is a check-then-act (TOCTOU) race that a better read can't fix and that in-process de-duplication can't cover across pods.

set overwrites (last-write-wins) and set_unique guarantees a unique value (not key ownership), so neither can elect a single winner. setIfAbsent can: the winner is decided atomically at the write, server-side, against the existing unique index on plugin_storage_items.

Motivating case: pacs-integration-service#202 (By The Bay / Habitap credential provisioning).

What's here

  • EnvoyStorageCommand — new set_if_absent action + EnvoySetIfAbsentStorageCommand.
  • EnvoyPluginStoragePipeline.setIfAbsent(...) and EnvoyPluginStorage.setIfAbsent(...).
  • Mock support in EnvoyPluginStoragePipelineMock (single-threaded existence check; TTL not modelled).
  • Tests: win / lost / no-overwrite-on-loss / reclaim-after-unset.
  • Design doc: docs/proposals/atomic-set-if-absent.md.

tsc --noEmit, eslint, and jest (76 passing, +4 new) are green.

Depends on

Platform companion PR in envoy-web adding the set_if_absent action to Platform::PluginStorageService. This SDK method is a no-op until that lands. The two can merge in either order.

🤖 Generated with Claude Code

Adds a race-free "write only if the key is not already set" command to plugin
storage: storage.setIfAbsent(key, value, { ttlSeconds? }) plus the pipeline
set_if_absent command. Resolves to the stored item on a win, or { value: undefined }
when the key already existed (claim lost) — mirroring the get-miss convention.

This is the client half; the platform (envoy-web PluginStorageService) must learn
the set_if_absent action for it to resolve. See docs/proposals/atomic-set-if-absent.md.

Motivation: integrations that provision from two concurrent paths (e.g. an event
webhook + an app-extension render, possibly on different pods) need a real
mutual-exclusion primitive. Today's get-then-set is a TOCTOU race and set_unique
overwrites. setIfAbsent lets exactly one caller win, resolved server-side against
the existing unique index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Zmatarasso

Copy link
Copy Markdown
Contributor Author

Platform companion PR: envoy/envoy-web#21455 (adds the set_if_absent action). This SDK method is inert until that lands; they can merge in either order.

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