Skip to content

fix: use singleton pattern for PhoneRistrettoCache and InMemoryCache#884

Merged
AchoArnold merged 2 commits into
mainfrom
fix/singleton-phone-and-memory-cache
May 13, 2026
Merged

fix: use singleton pattern for PhoneRistrettoCache and InMemoryCache#884
AchoArnold merged 2 commits into
mainfrom
fix/singleton-phone-and-memory-cache

Conversation

@AchoArnold
Copy link
Copy Markdown
Member

Summary

Apply the same singleton pattern already used by \UserRistrettoCache()\ to both \PhoneRistrettoCache()\ and \InMemoryCache()\ in the DI container.

Problem

Previously these methods created a new cache instance on every call, meaning each consumer got an isolated cache that could not be shared — defeating the purpose of caching.

Changes

  • Add \phoneRistrettoCache\ and \inMemoryCache\ fields to the \Container\ struct
  • Return the cached instance on subsequent calls instead of creating new ones
  • Fix error message in \PhoneRistrettoCache\ (previously said 'user ristretto cache')

Pattern

Follows the exact same nil-check singleton pattern already used by \UserRistrettoCache():

\\go
func (container *Container) PhoneRistrettoCache() *ristretto.Cache[string, *entities.Phone] {
if container.phoneRistrettoCache != nil {
return container.phoneRistrettoCache
}
// ... create and store
container.phoneRistrettoCache = ristrettoCache
return container.phoneRistrettoCache
}
\\

Apply the same singleton pattern already used by UserRistrettoCache to both
PhoneRistrettoCache and InMemoryCache in the DI container. Previously these
methods created a new cache instance on every call, meaning each consumer
got an isolated cache that could not be shared.

Changes:
- Add phoneRistrettoCache and inMemoryCache fields to Container struct
- Return cached instance on subsequent calls instead of creating new ones
- Fix error message in PhoneRistrettoCache (was 'user ristretto cache')

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 13, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 13, 2026

Greptile Summary

This PR fixes a caching bug where PhoneRistrettoCache() and InMemoryCache() created a fresh cache instance on every call, meaning no cache entries were ever shared between callers. The fix applies the same nil-check singleton pattern already used by UserRistrettoCache().

  • Two new fields (phoneRistrettoCache, inMemoryCache) are added to Container, and both methods now store and reuse the instance across calls.
  • The misleading error message "cannot create user ristretto cache" inside PhoneRistrettoCache is corrected to "cannot create phone ristretto cache".

Confidence Score: 5/5

Safe to merge — the change is a straightforward singleton fix that prevents redundant cache creation, and it mirrors a pattern already proven in the codebase.

The change is small and surgical: two fields added to the struct, two nil-check guards added to existing methods, and one wrong error string corrected. The new code is a direct copy of the UserRistrettoCache pattern that has been in production. No logic paths are removed, and no new dependencies are introduced.

No files require special attention; api/pkg/di/container.go is the only changed file and the modifications are contained to three well-isolated methods.

Important Files Changed

Filename Overview
api/pkg/di/container.go Applies the singleton nil-check pattern to PhoneRistrettoCache and InMemoryCache, adds two new struct fields, and corrects an error message. Changes are minimal and consistent with the existing UserRistrettoCache pattern.

Sequence Diagram

sequenceDiagram
    participant C as Caller
    participant CT as Container
    participant Cache as Cache Instance

    Note over CT: First call
    C->>CT: PhoneRistrettoCache()
    CT->>CT: "phoneRistrettoCache == nil?"
    CT->>Cache: ristretto.NewCache(...)
    Cache-->>CT: ristrettoCache
    CT->>CT: store container.phoneRistrettoCache
    CT-->>C: return phoneRistrettoCache

    Note over CT: Subsequent calls
    C->>CT: PhoneRistrettoCache()
    CT->>CT: "phoneRistrettoCache != nil"
    CT-->>C: return existing phoneRistrettoCache

    Note over CT: Same pattern for InMemoryCache
    C->>CT: InMemoryCache()
    CT->>CT: "inMemoryCache == nil?"
    CT->>Cache: ttlCache.New(...) + NewMemoryCache(...)
    Cache-->>CT: c
    CT->>CT: store container.inMemoryCache
    CT-->>C: return inMemoryCache
Loading

Reviews (1): Last reviewed commit: "fix: use singleton pattern for PhoneRist..." | Re-trigger Greptile

Comment thread api/pkg/di/container.go Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@AchoArnold AchoArnold merged commit f73a0e4 into main May 13, 2026
6 of 8 checks passed
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