go-pkgz / lcw Goto Github PK
View Code? Open in Web Editor NEWLoading Cache Wrapper
Home Page: https://go-pkgz.umputun.dev/lcw/
License: MIT License
Loading Cache Wrapper
Home Page: https://go-pkgz.umputun.dev/lcw/
License: MIT License
When lcw master will be tested in remark42 for enough time, I propose to release 0.6.0 with the following release notes:
- #11 introduce `LoadingCache.Close` function for proper LRU and Redis cache goroutines teardown
- #23 mention values mutability for LRU and Expirable cache in Readme, add code example for it
- #15 switch Expirable cache from `patrickmn/go-cache` to the internal implementation
- #11 stricter lint settings, bump dependencies
- #11 start running examples during tests
- #11 make tests work offline (had a dependency on internet connection)
- #11 #16 properly teardown goroutines to prevent their leakage in tests
Originally published in #23, moved there so it won't be lost in merged PR comments.
With go 1.18 we can make use of generics to simplify the API. I mean the primary access methods
Get(key string, fn func() (interface{}, error)) (val interface{}, err error) // load or get from cache
Peek(key string) (interface{}, bool)
this change will make usage much easier. In addition, we may want to update dependencies
note: this is a breaking change and should be released as v2. As of now, we don't even have v1, so we will need to tag the current one as v1.0.0 first
@paskal - let me know if you want to deal with this
With a large cache load, some serious memory leaks are possible. The buckets in map[K]V
are never reduced.
func TestBucketsLeak(t *testing.T) {
const n = 1_000_000
printAlloc := func() {
stats := runtime.MemStats{}
runtime.GC()
runtime.ReadMemStats(&stats)
t.Logf("alloc: %d Kb\n", stats.Alloc/1024)
}
lc, err := NewLoadingCache()
assert.NoError(t, err)
printAlloc()
for i := 0; i < n; i++ {
lc.Set(fmt.Sprintf("key-%d", i), fmt.Sprintf("val-%d", i))
}
printAlloc()
lc.Purge()
printAlloc()
// Prevents optimization
runtime.KeepAlive(lc)
}
=== RUN TestBucketsLeak
cache_test.go:213: alloc: 196 Kb
cache_test.go:213: alloc: 150528 Kb
cache_test.go:213: alloc: 56785 Kb
--- PASS: TestBucketsLeak (0.85s)
This idea implemented in go-phgz/rest/cahce and allows to invalidate multiple records inside of some scope(s).
This is needed if some change affects multiple cached records at once. For example, an update of the user's post may also need to invalidate the cached list of recent user's posts as well as another cached list of all last posts. To achieve it two scopes should be used - last_<user_id> and "last_all_posts" and invalidate will be called with those scopes.
The goal is to implement RedisCache
satisfying LoadingCache
The goal is to pass some URI, like redis://127.0.0.1:123?max=12&ttl=60s
or mem://lru?fo-bar
and get back fully constructed cache.
Such functionality may simplify client code supporting multiple cache configuration. In fact, it will move the switch from the client-side to lcw package and minimize the number of params client has to provide & maintain (a single url instead of multiple params).
The goal is to allow multiple nodes running LoadingCache to work together in an eventually consistent way. The simplest solution is to propagate the invalidation request to all nodes on each cache update or removal. Probably some pub-sub mechanism will fit.
$subj, stored value (at least for non-Redis cache) is mutable. We should have documentation and test\example showing this case.
With introduction of generics to golang, can this lib implement support for custom structs as key ?
With probability higher than 20% locally and than 50% on GitHub Actions, TestCache_MaxCacheSizeParallel/LruCache
fails with race condition. It's seen as LruCache.currentSize
wrong values \ concurrent changes despite the fact that all changes are done using atomic.AddInt64
and atomic.LoadInt64
.
If somebody would be able to fix code in a way it won't fail, it would be great.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.