Skip to content

feat: add Dapr distributed cache provider - #2870

Open
fseldow wants to merge 2 commits into
notaryproject:mainfrom
fseldow:fseldow/v2-dapr-cache
Open

feat: add Dapr distributed cache provider#2870
fseldow wants to merge 2 commits into
notaryproject:mainfrom
fseldow:fseldow/v2-dapr-cache

Conversation

@fseldow

@fseldow fseldow commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

Ports the Dapr cache provider from Ratify v1 (pkg/cache/dapr) to v2, enabling the high-availability deployment mode where verify/mutate cache state is shared across replicas via a Dapr state store.

Changes

  • internal/cache/dapr: new provider implementing the generic cache.Cache[T] interface. Values are JSON-encoded so any T can be shared across replicas. Keys are namespaced via internal/context.CreateCacheKey, and construction is gated by the EXPERIMENTAL_HIGH_AVAILABILITY feature flag.
    • v1's separate Set/SetWithTTL are merged into a single Set(ctx, key, value, ttl) to match the v2 Ristretto/in-memory providers; a non-positive TTL falls back to the configured default.
    • Get returns cache.ErrNotFound when the state entry is empty, honoring the v2 cache contract.
  • internal/httpserver: cache creation now goes through a newCache[T] helper that returns the Dapr cache when high-availability is enabled, otherwise Ristretto. Default behavior is unchanged.
  • Adds the github.com/dapr/go-sdk dependency and unit tests mirroring the v1 coverage.

Testing

  • go build ./...
  • go test ./internal/cache/... ./internal/httpserver/... — all pass
  • golangci-lint on the new package — 0 issues

Note: the high-availability path is inert unless RATIFY_EXPERIMENTAL_HIGH_AVAILABILITY=1 and a Dapr sidecar are present, so default deployments are unaffected.

Port the Dapr cache provider from Ratify v1 to v2, enabling the
high-availability deployment mode where verify/mutate cache state is
shared across replicas via a Dapr state store.

- Add internal/cache/dapr implementing the generic cache.Cache[T]
  interface (JSON-encoding values), gated by the HighAvailability
  feature flag and namespacing keys via internal/context.
- Wire the server cache creation to use the Dapr cache when
  high-availability is enabled, falling back to Ristretto otherwise.
- Add github.com/dapr/go-sdk dependency and unit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 4, 2026 05:36
@github-actions github-actions Bot added the v2 label Aug 4, 2026
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.00000% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.29%. Comparing base (1fbd74f) to head (6199d96).

Files with missing lines Patch % Lines
internal/cache/dapr/dapr.go 55.81% 17 Missing and 2 partials ⚠️
internal/httpserver/server.go 66.66% 1 Missing and 1 partial ⚠️

❌ Your patch check has failed because the patch coverage (58.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2870      +/-   ##
==========================================
- Coverage   76.53%   76.29%   -0.24%     
==========================================
  Files          88       89       +1     
  Lines        4027     4075      +48     
==========================================
+ Hits         3082     3109      +27     
- Misses        799      817      +18     
- Partials      146      149       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR ports the Dapr-backed distributed cache provider from Ratify v1 into the v2 codebase to support the experimental high-availability mode where verify/mutate cache state can be shared across replicas via a Dapr state store.

Changes:

  • Adds a new generic Dapr cache provider (internal/cache/dapr) implementing cache.Cache[T] using JSON encoding and Dapr state APIs (with optional TTL metadata).
  • Updates the HTTP server to construct caches via a newCache[T] helper that selects Dapr when the high-availability feature flag is enabled, otherwise falling back to Ristretto.
  • Introduces the github.com/dapr/go-sdk dependency.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/httpserver/server.go Routes cache construction through a helper to switch between Ristretto and the new Dapr cache based on a feature flag.
internal/cache/dapr/dapr.go Implements a Dapr state-store-backed cache with JSON serialization and TTL support.
internal/cache/dapr/dapr_test.go Adds unit tests for Dapr cache Get/Set/Delete using a stubbed Dapr client.
go.mod Adds github.com/dapr/go-sdk dependency (and related indirect deps).
go.sum Adds checksums for the new dependency set.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +141 to 144
mutateCache, err := newCache[string](defaultCacheTTL)
if err != nil {
return nil, nil, fmt.Errorf("failed to create mutate cache: %w", err)
}
Comment on lines +108 to +111
var md map[string]string
if ttl > 0 {
md = map[string]string{"ttlInSeconds": strconv.Itoa(int(ttl.Seconds()))}
}
- Call featureflag.InitFeatureFlagsFromEnv() at startup so
  RATIFY_EXPERIMENTAL_HIGH_AVAILABILITY actually enables the Dapr cache
  path at runtime (previously only initialized in tests).
- Compute ttlInSeconds with integer duration math and round up, so any
  positive sub-second TTL maps to at least 1 second instead of an
  unintended ttlInSeconds=0. Add a sub-second TTL test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fseldow

fseldow commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the AI review feedback in 6199d96:

  1. Feature flags not initialized at runtime — added featureflag.InitFeatureFlagsFromEnv() in main() so RATIFY_EXPERIMENTAL_HIGH_AVAILABILITY=1 now actually enables the Dapr cache path.
  2. TTL truncationttlInSeconds is now computed with integer duration math and rounded up, so any positive sub-second TTL maps to at least 1 second (no more unintended ttlInSeconds=0). Added a sub-second TTL test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants