-
Notifications
You must be signed in to change notification settings - Fork 0
Add SyncMap cache implementation and tests #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
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 adds a new cache implementation based on Go's sync.Map and includes corresponding tests and a minor .gitignore update. The implementation provides a simple, thread-safe in-memory cache that conforms to the Cache[T] interface defined in the codebase.
- Implements
SyncMap[T]cache backed bysync.Mapwith generic type safety - Adds basic test coverage for the cache implementation
- Updates .gitignore to exclude .windsurf directory
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| syncmap.go | Implements SyncMap cache with Set, Get, and Del methods using embedded sync.Map |
| syncmap_test.go | Adds tests covering basic CRUD operations and embedded sync.Map method access |
| .gitignore | Adds .windsurf IDE directory to ignore list |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| type SyncMap[T any] struct { | ||
| sync.Map |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Embedding sync.Map exposes its untyped methods (Store, Load, Delete, Range, etc.) which bypass the generic type safety provided by the Cache interface. This creates a confusing API where users can accidentally store values of the wrong type using cache.Store() directly, leading to runtime panics in Get(). Consider using composition instead of embedding (e.g., having a private field 'data sync.Map') to maintain type safety and provide a cleaner API surface.
| func TestSyncMapEmbeddedMethods(t *testing.T) { | ||
| cache := NewSyncMap[int]() | ||
|
|
||
| cache.Store("a", 1) | ||
| cache.Store("b", 2) | ||
|
|
||
| v, ok := cache.Load("a") | ||
| require.True(t, ok) | ||
| assert.Equal(t, 1, v) | ||
|
|
||
| count := 0 | ||
| cache.Range(func(k, v any) bool { | ||
| count++ | ||
| return true | ||
| }) | ||
| assert.Equal(t, 2, count) | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test demonstrates accessing embedded sync.Map methods directly, which bypasses type safety and can lead to runtime panics. While this test verifies that the embedding works, it doesn't test the critical failure scenario: what happens when someone stores a value of the wrong type (e.g., cache.Store("a", "wrongtype")) and then calls the typed Get method. This scenario would cause a panic that should be either tested or prevented through better API design.
| if !ok { | ||
| return zero, errors.Wrapf(&ErrKeyNotFound{}, "key not found in syncmap for key: %s", key) | ||
| } | ||
| return v.(T), nil |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unchecked type assertion can panic if a value of the wrong type is stored. This is particularly dangerous because the embedded sync.Map allows direct access to Store/Load/Range methods, which bypass the generic type safety. For example, if someone calls cache.Store("key", wrongTypeValue) directly and then calls cache.Get(ctx, "key"), the type assertion will panic. Consider either: (1) using a safe type assertion with ok check and returning an error if types don't match, or (2) not embedding sync.Map to prevent direct access to its methods.
xRef: