Skip to content
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

Fixed an timing issue with near cache clear #74

Merged
merged 1 commit into from Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions coherence/cache.go
Expand Up @@ -198,6 +198,9 @@ type NamedMap[K comparable, V any] interface {
// GetNearCacheStats returns the [CacheStats] for a near cache for a [NamedMap] or [NamedCache].
// If no near cache is defined, nil is returned.
GetNearCacheStats() CacheStats

// GetCacheName returns the cache name of the [NamedMap] or [NamedCache].
GetCacheName() string
}

// NamedCache is syntactically identical in behaviour to a NamedMap, but additionally implements
Expand Down
4 changes: 2 additions & 2 deletions coherence/common.go
Expand Up @@ -132,7 +132,7 @@ func executeClear[K comparable, V any](ctx context.Context, bc *baseClient[K, V]
_, err = bc.client.Clear(newCtx, &clearRequest)

// clear the near cache
if err != nil && nearCache != nil {
if nearCache != nil {
nearCache.Clear()
}

Expand Down Expand Up @@ -238,7 +238,7 @@ func executeTruncate[K comparable, V any](ctx context.Context, bc *baseClient[K,
_, err = bc.client.Truncate(newCtx, &request)

// clear the near cache
if err != nil && nearCache != nil {
if nearCache != nil {
nearCache.Clear()
}

Expand Down
6 changes: 3 additions & 3 deletions coherence/event.go
Expand Up @@ -186,7 +186,7 @@ func (l *mapLifecycleEvent[K, V]) Source() NamedMap[K, V] {

// String returns a string representation of a MapLifecycleEvent.
func (l *mapLifecycleEvent[K, V]) String() string {
return fmt.Sprintf("MapLifecycleEvent{source=%v, type=%s}", l.Source(), l.Type())
return fmt.Sprintf("MapLifecycleEvent{source=%v, type=%s}", l.Source().GetCacheName(), l.Type())
}

// MapEvent an event which indicates that the content of the NamedMap or
Expand Down Expand Up @@ -321,8 +321,8 @@ func (e *mapEvent[K, V]) String() string {
}
return *val
}
return fmt.Sprintf("MapEvent{source=%v, name=%s, type=%s, key=%s, oldValue=%s, newValue=%s}",
source, source.Name(), e.eventType, keyEval(key, keyErr), valueEval(oldValue, oldErr), valueEval(newValue, newErr))
return fmt.Sprintf("MapEvent{source=%v, name=%s, type=%s, key=%v, oldValue=%v, newValue=%v}",
source.GetCacheName(), source.Name(), e.eventType, keyEval(key, keyErr), valueEval(oldValue, oldErr), valueEval(newValue, newErr))
}

type SessionLifecycleListener interface {
Expand Down
5 changes: 5 additions & 0 deletions coherence/named_cache_client.go
Expand Up @@ -28,6 +28,11 @@ func (nc *NamedCacheClient[K, V]) getBaseClient() *baseClient[K, V] { // nolint
return &nc.baseClient
}

// GetCacheName returns the cache name of the [NamedCache].
func (nc *NamedCacheClient[K, V]) GetCacheName() string {
return nc.name
}

// AddLifecycleListener Adds a [MapLifecycleListener] that will receive events (truncated or released) that occur
// against the [NamedCache].
func (nc *NamedCacheClient[K, V]) AddLifecycleListener(listener MapLifecycleListener[K, V]) {
Expand Down
5 changes: 5 additions & 0 deletions coherence/named_map_client.go
Expand Up @@ -248,6 +248,11 @@ func RemoveIndex[K comparable, V, T, E any](ctx context.Context, nm NamedMap[K,
return executeRemoveIndex(ctx, nm.getBaseClient(), extractor)
}

// GetCacheName returns the cache name of the [NamedMap].
func (nm *NamedMapClient[K, V]) GetCacheName() string {
return nm.name
}

// AddLifecycleListener adds a [MapLifecycleListener] that will receive events (truncated or released) that occur
// against the [NamedMap].
func (nm *NamedMapClient[K, V]) AddLifecycleListener(listener MapLifecycleListener[K, V]) {
Expand Down
51 changes: 49 additions & 2 deletions test/e2e/standalone/near_cache_test.go
Expand Up @@ -39,8 +39,10 @@ func TestNearCacheOperationsAgainstMapAndCache(t *testing.T) {
nameMap coherence.NamedMap[int, Person]
test func(t *testing.T, namedCache coherence.NamedMap[int, Person])
}{
{"TestNearCacheBasicNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-basic-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
{"TestNearCacheBasicNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-basic-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
{"RunTestNearCacheBasicNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-basic-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
{"RunTestNearCacheBasicNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-basic-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
{"RunTestNearWithClearNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-clear-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearWithClear},
{"RunTestNearWithClearNamedMap", GetNearCacheNamedCache[int, Person](g, session, "near-cache-clear-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearWithClear},
{"RunTestNearCacheRemovesNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-removes-map", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheRemoves},
{"RunTestNearCacheRemovesNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-removes-cache", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheRemoves},
{"RunTestNearCacheContainsKeyNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-removes-map", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheContainsKey},
Expand Down Expand Up @@ -347,6 +349,51 @@ func RunTestNearCacheWithHighUnits(t *testing.T, namedMap coherence.NamedMap[int
g.Expect(namedMap.GetNearCacheStats().GetCachePrunes()).To(gomega.Equal(int64(1)))
}

// RunTestNearWithClear tests a near cache that issues puts, get then clears..
func RunTestNearWithClear(t *testing.T, namedMap coherence.NamedMap[int, Person]) {
var (
g = gomega.NewWithT(t)
err error
p1Get *Person
p2Get *Person
)

err = namedMap.Clear(ctx)
g.Expect(err).ShouldNot(gomega.HaveOccurred())

p1 := Person{ID: 1, Name: "p1"}
p2 := Person{ID: 2, Name: "p2"}

for i := 1; i < 100; i++ {
_, err = namedMap.Put(ctx, p1.ID, p1)
g.Expect(err).ShouldNot(gomega.HaveOccurred())

_, err = namedMap.Put(ctx, p2.ID, p2)
g.Expect(err).ShouldNot(gomega.HaveOccurred())

AssertSize[int, Person](g, namedMap, 2)

p1Get, err = namedMap.Get(ctx, p1.ID)
g.Expect(err).ShouldNot(gomega.HaveOccurred())
g.Expect(*p1Get).Should(gomega.Equal(p1))

p2Get, err = namedMap.Get(ctx, p2.ID)
g.Expect(err).ShouldNot(gomega.HaveOccurred())
g.Expect(*p2Get).Should(gomega.Equal(p2))

err = namedMap.Clear(ctx)
g.Expect(err).ShouldNot(gomega.HaveOccurred())

p1Get, err = namedMap.Get(ctx, p1.ID)
g.Expect(err).ShouldNot(gomega.HaveOccurred())
g.Expect(p1Get).Should(gomega.BeNil())

p2Get, err = namedMap.Get(ctx, p2.ID)
g.Expect(err).ShouldNot(gomega.HaveOccurred())
g.Expect(p2Get).Should(gomega.BeNil())
}
}

// RunTestNearCacheWithHighUnits tests near cache with high units of 100 and accessing entries to ensure they are not removed.
func RunTestNearCacheWithHighUnitsAccess(t *testing.T, namedMap coherence.NamedMap[int, Person]) {
var (
Expand Down