Skip to content

feat(api):refactor alias cache to redis - #1914

Merged
jakubno merged 5 commits into
mainfrom
feat/alias-cache-refactor-to-redis-eng-3505
Feb 19, 2026
Merged

jakubno merged 5 commits into
mainfrom
feat/alias-cache-refactor-to-redis-eng-3505

Conversation

@jakubno

@jakubno jakubno commented Feb 14, 2026 •

Copy link
Copy Markdown
Member

Note

Medium Risk
Touches core cache invalidation and alias resolution paths and introduces Redis scripts/pipelining, so bugs could cause stale or missing alias mappings across processes. Behavioral intent is preserved and covered by updated integration tests against Redis.

Overview
Refactors template alias resolution caching to use Redis instead of in-process memory, including Redis-backed negative caching tombstones and backfilling lookups by template ID.

Adds a Redis reverse-index per templateID (set + Lua pop) so InvalidateByTemplateID can efficiently delete all alias/id cache keys across a cluster, updates invalidation call sites to pass context.Context (using context.WithoutCancel where needed), and standardizes Redis operations on a shared RedisDefaultTimeout (removing per-cache timeouts and adjusting tests to assert Redis key presence/deletion).

Written by Cursor Bugbot for commit 68cbe79. This will update automatically on new commits. Configure here.

@linear

linear Bot commented Feb 14, 2026

Copy link
Copy Markdown

Comment thread packages/api/internal/cache/templates/alias_cache_redis.go Outdated
Comment thread packages/api/internal/cache/templates/alias_cache_redis.go Outdated
Comment thread packages/api/internal/cache/templates/alias_cache.go Outdated
Comment thread packages/api/internal/cache/templates/alias_cache.go Outdated
Comment thread packages/api/internal/cache/templates/alias_cache_redis.go Outdated
Comment thread packages/api/internal/cache/templates/alias_cache_redis.go Outdated
@jakubno
jakubno force-pushed the feat/alias-cache-refactor-to-redis-eng-3505 branch from df24895 to 75bb7ca Compare February 16, 2026 01:25
@jakubno
jakubno changed the base branch from main to feat/move-templates-cache-to-redis-eng-3064 February 16, 2026 01:27
@jakubno
jakubno force-pushed the feat/alias-cache-refactor-to-redis-eng-3505 branch from 75bb7ca to 8b5eab4 Compare February 16, 2026 01:27
Comment thread packages/api/internal/cache/templates/alias_cache.go Outdated
@dobrac dobrac self-assigned this Feb 17, 2026
@@ -97,8 +103,8 @@ func (c *AliasCache) Resolve(ctx context.Context, identifier string, namespaceFa
return nil, err
}

// lookup performs a single lookup (cache then DB) for namespace/alias.
// Caches both positive hits and negative hits to avoid repeated DB queries.
// lookup performs a single lookup using memory → Redis → DB for namespace/alias.

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.

is it actually using anything in memory?

@jakubno
jakubno force-pushed the feat/move-templates-cache-to-redis-eng-3064 branch from ba29230 to c36f5c7 Compare February 18, 2026 20:06
Base automatically changed from feat/move-templates-cache-to-redis-eng-3064 to main February 19, 2026 03:18
@jakubno
jakubno force-pushed the feat/alias-cache-refactor-to-redis-eng-3505 branch from 8b5eab4 to f61a55e Compare February 19, 2026 06:43
Comment thread packages/api/internal/cache/templates/alias_cache.go
Comment thread packages/api/internal/cache/templates/template_build.go Outdated
Comment thread packages/api/internal/cache/templates/cache_test.go

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.


return info, nil
// Track alias key in reverse index for InvalidateByTemplateID
c.trackReverseKey(ctx, originalKey, idKey, info)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Race between cache fill and reverse index invalidation

Low Severity

cacheByTemplateID runs inside fetchFromDB's defer, which executes before GetOrSet writes the original alias key to Redis. This means trackReverseKey registers the originalKey in the reverse index before that key actually exists in Redis. If InvalidateByTemplateID runs in this narrow window, the DEL for the original key is a no-op, and then GetOrSet writes it afterward — leaving a stale cache entry that the reverse index no longer tracks. It self-heals via TTL expiry but could serve stale data for up to aliasCacheTTL.

Additional Locations (1)

Fix in Cursor Fix in Web

@jakubno
jakubno marked this pull request as ready for review February 19, 2026 20:07
@jakubno
jakubno merged commit a6a8ae8 into main Feb 19, 2026
35 checks passed
@jakubno
jakubno deleted the feat/alias-cache-refactor-to-redis-eng-3505 branch February 19, 2026 20:07

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68cbe79f82

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +227 to +229
local members = redis.call("SMEMBERS", KEYS[1])
redis.call("DEL", KEYS[1])
return members

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep reverse index until all alias keys are deleted

The Lua pop script deletes the reverse-index set before the subsequent DEL pipeline runs, so if the pipeline times out or fails (for example, templates with many cached aliases or transient Redis slowness under the shared 2s timeout in InvalidateByTemplateID), we permanently lose the member list needed for retries and stale alias/id cache entries can survive until TTL expiry. This turns a transient Redis failure into persistent stale routing for that template.

Useful? React with 👍 / 👎.

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.

3 participants