Skip to content

Conversation

@kuujo
Copy link
Member

@kuujo kuujo commented Feb 11, 2020

This PR adds support for wrapping a Map primitive in an LRU cache.

To cache a map, just use the WithCache option when constructing the map:

m, err := client.GetMap(context.TODO(), "my-map", _map.WithCache(1000))

The cache is implemented using Hashicorp's LRU cache. When a client writes to the cache, any existing cached entries are deleted. A background goroutine listens for update events from the cluster to populate the cache. Because of the consistency guarantees of Atomix sessions, this guarantees a client will receive the same consistency guarantees as an uncached client.

@@ -0,0 +1,136 @@
// Copyright 2019-present Open Networking Foundation.
Copy link
Member Author

Choose a reason for hiding this comment

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

Need to update the copyright header in my IDE 😄

for event := range ch {
switch event.Type {
case EventNone:
m.cache.Add(event.Entry.Key, event.Entry)
Copy link
Member Author

Choose a reason for hiding this comment

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

These cache writes need to be locked

// This check is performed because a concurrent event could update the cached entry
m.mu.Lock()
prevEntry, ok := m.cache.Get(key)
if !ok || prevEntry.(*Entry).Version < entry.Version {
Copy link
Member Author

Choose a reason for hiding this comment

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

This condition is unsafe for the same reason it’s unsafe on Get: a later Remove would make this version check impossible without maintaining tombstones. The entries just have to be removed from the cache.

@kuujo
Copy link
Member Author

kuujo commented Feb 11, 2020

I think this doesn’t actually provide RYW consistency. Cache hits read from an event stream, and cache misses from the database. But in the Go client, events are not serialized with reads, so it’s possible a cache miss can occur after a later cache hit in logical time.

@adibrastegarnia adibrastegarnia merged commit 6fd69e6 into master Feb 18, 2020
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