Overview
There are several good in-memory cache libraries for Golang, but I needed something lightweight and simple, so I decided to implement one myself.
Implementation
Requirements
- Should be able to store multiple data entries.
- Should store data in memory with an expiration time. Data should be discarded from memory once expired.
- Should handle concurrent access and updates to the cache, with proper locking mechanisms.
Initial Design
Note: The code is available at github.com - bmf-san/go-snippets/architecture_design/cache/cache.go.
This is the initial implementation based on my first idea:
I initially thought sync.Map was convenient because it eliminates the need to handle locking manually. However, due to its data structure and functionality, it did not meet the requirements, so I decided against using it.
Release Version
Note: The code is available at github.com - bmf-san/go-snippets/architecture_design/cache/cache_with_goroutine.go.
This is the version that meets the requirements:
Although sync.Map is convenient, it became challenging to check and delete expired cache data without specifying cache keys. Therefore, I decided to use a map to store the cache data.
The expiration check is performed at intervals using a ticker. In the above implementation, the interval is set to one second. However, this means that cached data can still be accessed for up to one second after its expiration time, effectively making the expiration time equal to the specified time plus the interval.
Thoughts
This was a good opportunity to get started with concurrency and locking in Golang.