Skip to content

Commit 2178d2d

Browse files
authored
Fixed an timing issue with near cache clear (#74)
1 parent 26284bb commit 2178d2d

File tree

6 files changed

+67
-7
lines changed

6 files changed

+67
-7
lines changed

coherence/cache.go

+3
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ type NamedMap[K comparable, V any] interface {
198198
// GetNearCacheStats returns the [CacheStats] for a near cache for a [NamedMap] or [NamedCache].
199199
// If no near cache is defined, nil is returned.
200200
GetNearCacheStats() CacheStats
201+
202+
// GetCacheName returns the cache name of the [NamedMap] or [NamedCache].
203+
GetCacheName() string
201204
}
202205

203206
// NamedCache is syntactically identical in behaviour to a NamedMap, but additionally implements

coherence/common.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func executeClear[K comparable, V any](ctx context.Context, bc *baseClient[K, V]
132132
_, err = bc.client.Clear(newCtx, &clearRequest)
133133

134134
// clear the near cache
135-
if err != nil && nearCache != nil {
135+
if nearCache != nil {
136136
nearCache.Clear()
137137
}
138138

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

240240
// clear the near cache
241-
if err != nil && nearCache != nil {
241+
if nearCache != nil {
242242
nearCache.Clear()
243243
}
244244

coherence/event.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func (l *mapLifecycleEvent[K, V]) Source() NamedMap[K, V] {
186186

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

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

328328
type SessionLifecycleListener interface {

coherence/named_cache_client.go

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ func (nc *NamedCacheClient[K, V]) getBaseClient() *baseClient[K, V] { // nolint
2828
return &nc.baseClient
2929
}
3030

31+
// GetCacheName returns the cache name of the [NamedCache].
32+
func (nc *NamedCacheClient[K, V]) GetCacheName() string {
33+
return nc.name
34+
}
35+
3136
// AddLifecycleListener Adds a [MapLifecycleListener] that will receive events (truncated or released) that occur
3237
// against the [NamedCache].
3338
func (nc *NamedCacheClient[K, V]) AddLifecycleListener(listener MapLifecycleListener[K, V]) {

coherence/named_map_client.go

+5
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ func RemoveIndex[K comparable, V, T, E any](ctx context.Context, nm NamedMap[K,
248248
return executeRemoveIndex(ctx, nm.getBaseClient(), extractor)
249249
}
250250

251+
// GetCacheName returns the cache name of the [NamedMap].
252+
func (nm *NamedMapClient[K, V]) GetCacheName() string {
253+
return nm.name
254+
}
255+
251256
// AddLifecycleListener adds a [MapLifecycleListener] that will receive events (truncated or released) that occur
252257
// against the [NamedMap].
253258
func (nm *NamedMapClient[K, V]) AddLifecycleListener(listener MapLifecycleListener[K, V]) {

test/e2e/standalone/near_cache_test.go

+49-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ func TestNearCacheOperationsAgainstMapAndCache(t *testing.T) {
3939
nameMap coherence.NamedMap[int, Person]
4040
test func(t *testing.T, namedCache coherence.NamedMap[int, Person])
4141
}{
42-
{"TestNearCacheBasicNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-basic-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
43-
{"TestNearCacheBasicNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-basic-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
42+
{"RunTestNearCacheBasicNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-basic-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
43+
{"RunTestNearCacheBasicNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-basic-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearCacheBasic},
44+
{"RunTestNearWithClearNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-clear-cache", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearWithClear},
45+
{"RunTestNearWithClearNamedMap", GetNearCacheNamedCache[int, Person](g, session, "near-cache-clear-map", coherence.WithNearCache(&nearCacheOptions10Seconds)), RunTestNearWithClear},
4446
{"RunTestNearCacheRemovesNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-removes-map", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheRemoves},
4547
{"RunTestNearCacheRemovesNamedCache", GetNearCacheNamedCache[int, Person](g, session, "near-cache-removes-cache", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheRemoves},
4648
{"RunTestNearCacheContainsKeyNamedMap", GetNearCacheNamedMap[int, Person](g, session, "near-cache-removes-map", coherence.WithNearCache(&nearCacheOptions120Seconds)), RunTestNearCacheContainsKey},
@@ -347,6 +349,51 @@ func RunTestNearCacheWithHighUnits(t *testing.T, namedMap coherence.NamedMap[int
347349
g.Expect(namedMap.GetNearCacheStats().GetCachePrunes()).To(gomega.Equal(int64(1)))
348350
}
349351

352+
// RunTestNearWithClear tests a near cache that issues puts, get then clears..
353+
func RunTestNearWithClear(t *testing.T, namedMap coherence.NamedMap[int, Person]) {
354+
var (
355+
g = gomega.NewWithT(t)
356+
err error
357+
p1Get *Person
358+
p2Get *Person
359+
)
360+
361+
err = namedMap.Clear(ctx)
362+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
363+
364+
p1 := Person{ID: 1, Name: "p1"}
365+
p2 := Person{ID: 2, Name: "p2"}
366+
367+
for i := 1; i < 100; i++ {
368+
_, err = namedMap.Put(ctx, p1.ID, p1)
369+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
370+
371+
_, err = namedMap.Put(ctx, p2.ID, p2)
372+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
373+
374+
AssertSize[int, Person](g, namedMap, 2)
375+
376+
p1Get, err = namedMap.Get(ctx, p1.ID)
377+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
378+
g.Expect(*p1Get).Should(gomega.Equal(p1))
379+
380+
p2Get, err = namedMap.Get(ctx, p2.ID)
381+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
382+
g.Expect(*p2Get).Should(gomega.Equal(p2))
383+
384+
err = namedMap.Clear(ctx)
385+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
386+
387+
p1Get, err = namedMap.Get(ctx, p1.ID)
388+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
389+
g.Expect(p1Get).Should(gomega.BeNil())
390+
391+
p2Get, err = namedMap.Get(ctx, p2.ID)
392+
g.Expect(err).ShouldNot(gomega.HaveOccurred())
393+
g.Expect(p2Get).Should(gomega.BeNil())
394+
}
395+
}
396+
350397
// RunTestNearCacheWithHighUnits tests near cache with high units of 100 and accessing entries to ensure they are not removed.
351398
func RunTestNearCacheWithHighUnitsAccess(t *testing.T, namedMap coherence.NamedMap[int, Person]) {
352399
var (

0 commit comments

Comments
 (0)