Skip to content

Commit

Permalink
Bug 37311625 - [37264961->15.1.1.0.0] CQC constructor with fCacheValu…
Browse files Browse the repository at this point in the history
…es of false should configure lite mapListener (main->main.net)

Validated with Jenkins shelf build Coh-NET-main: #1380. 

[git-p4: depot-paths = "//dev/main.net/": change = 112998]
  • Loading branch information
jfialli committed Dec 17, 2024
1 parent e5d9793 commit 3d1b238
Show file tree
Hide file tree
Showing 3 changed files with 443 additions and 10 deletions.
25 changes: 19 additions & 6 deletions src/Coherence/Net/Cache/ContinuousQueryCache.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
Expand Down Expand Up @@ -134,11 +134,15 @@ public virtual bool IsCacheValues
/// <b>true</b> if this object caches values locally, and false if it
/// relies on the underlying <b>INamedCache</b>.
/// </value>
/// <p>
/// Note that a non-null <see cref="Transformer"/> or a <b>isLite</b> parameter of <b>false</b>
/// passed to <see cref="IObservableCache.AddCacheListener(ICacheListener, IFilter, bool)"/> forces
/// <b>CacheValues</b> to always be <b>true</b>.</p>
public virtual bool CacheValues
{
get
{
return m_cacheValues || IsObserved;
return m_cacheValues || IsObserved || Transformer != null;
}
set
{
Expand Down Expand Up @@ -512,6 +516,7 @@ public ContinuousQueryCache(INamedCache cache, IFilter filter, IValueExtractor t
/// <param name="isCacheValues">
/// Pass <b>true</b> to cache both the keys and values of the
/// materialized view locally, or <b>false</b> to only cache the keys.
/// Override of <b>false</b> described in <see cref="CacheValues"/>.
/// </param>
public ContinuousQueryCache(INamedCache cache, IFilter filter, bool isCacheValues)
: this(() => cache, filter, isCacheValues, null, null)
Expand Down Expand Up @@ -562,6 +567,7 @@ public ContinuousQueryCache(INamedCache cache, IFilter filter, ICacheListener li
/// <param name="cacheValues">
/// Pass <b>true</b> to cache both the keys and values of the
/// materialized view locally, or <b>false</b> to only cache the keys.
/// Override of <b>false</b> described in <b>CacheValues</b>.
/// </param>
/// <param name="cacheListener">
/// The optional <b>ICacheListener</b> that will receive all events
Expand All @@ -571,7 +577,11 @@ public ContinuousQueryCache(INamedCache cache, IFilter filter, ICacheListener li
/// The transformer that should be used to convert values from the
/// underlying cache before storing them locally
/// </param>
public ContinuousQueryCache(Func<INamedCache> supplierCache, IFilter filter, bool cacheValues,
/// <p>
/// Note when parameter <b>cacheValues</b> is <b>false</b>, it is inferred that provided parameter
/// <b>cacheListener</b> is a lite listener as described by <b>isLite</b> parameter of
/// <see cref="IObservableCache.AddCacheListener(ICacheListener, IFilter, bool)"/>.</p>
public ContinuousQueryCache(Func<INamedCache> supplierCache, IFilter filter, bool cacheValues,
ICacheListener cacheListener, IValueExtractor transformer)
{
INamedCache cache = supplierCache();
Expand Down Expand Up @@ -601,6 +611,9 @@ public ContinuousQueryCache(Func<INamedCache> supplierCache, IFilter filter, boo
m_state = CacheState.Disconnected;
m_cacheListener = cacheListener;

// initialize IsObserved on whether a standard (non-lite) listener passed in at construction time
m_hasListeners = cacheListener != null && cacheValues;

// by including information about the underlying cache, filter and
// transformer, the resulting cache name is convoluted but extremely
// helpful for tasks such as debugging
Expand Down Expand Up @@ -2596,13 +2609,13 @@ protected IObservableCache EnsureInternalCache()
if (m_cacheLocal == null)
{
IObservableCache cacheLocal = m_cacheLocal = InstantiateInternalCache();
ICacheListener cacheListener = m_cacheListener;
ICacheListener cacheListener = m_cacheListener;
bool isLite = !CacheValues;
if (cacheListener != null)
{
// the initial listener has to hear the initial events
EnsureEventDispatcher();
cacheLocal.AddCacheListener(InstantiateEventRouter(cacheListener, false));
m_hasListeners = true;
cacheLocal.AddCacheListener(InstantiateEventRouter(cacheListener, isLite), (IFilter) null, isLite);
}
}
return m_cacheLocal;
Expand Down
233 changes: 231 additions & 2 deletions tests/Coherence.Tests/Net/Cache/CQCProxyTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
* https://oss.oracle.com/licenses/upl.
*/
using System;
using System.Collections;
Expand Down Expand Up @@ -117,6 +117,112 @@ public void TestEvents()
Assert.AreEqual(SOME_DATA, listener.GetActualTotal());
}

/// <summary>
/// TestEvents with CacheValues of false.
/// </summary>
[Test]
public void TestEventsNoValues()
{
// start the ProxyService on just one cluster node
IInvocationService invocationService = RestartProxy(null);

// put data items into inner cache to generate events
INamedCache testCache = GetCache("proxy-stop-test");
testCache.Clear();
IDictionary dict = new Hashtable();
for (int i = 0; i < SOME_DATA; i++)
{
dict.Add("TestKey" + i, i);
}
testCache.InsertAll(dict);

// create listener for CQC
ValidateLiteListener listener = new ValidateLiteListener(SOME_DATA);

// instantiate the CQC, will start the test running.
ContinuousQueryCache queryCache =
new ContinuousQueryCache(() => testCache, AlwaysFilter.Instance,
false, listener, null);
theCQC = queryCache;
Assert.IsFalse(queryCache.CacheValues);

// instantiate a service listener to receive memberLeft event
fMemberLeft = false;
testCache.CacheService.MemberLeft += new MemberEventHandler(OnMemberLeft);

// allow test time to complete
using (ThreadTimeout t = ThreadTimeout.After(30000))
{
while (listener.GetActualTotal() < SOME_DATA)
{
Blocking.Sleep(250);
}
}

// check listener received the correct number of events.
Assert.AreEqual(SOME_DATA, listener.GetActualTotal());
listener.ResetActualTotal();

// restart proxy
RestartProxy(invocationService);

using (ThreadTimeout t = ThreadTimeout.After(30000))
{
while (!fMemberLeft)
{
Blocking.Sleep(250);
}
}

// ping the CQC to make it realize the cache needs restart
theCQC.Contains("junkstuff");

// allow test time to complete.
using (ThreadTimeout t = ThreadTimeout.After(30000))
{
while (listener.GetActualTotal() < SOME_DATA)
{
Blocking.Sleep(250);
}
}

Assert.AreEqual(SOME_DATA, listener.GetActualTotal());
}

/// <summary>
/// TestEvents with CacheValues of false. After standard listener (non-lite) added, CacheValues overriden to true.
/// </summary>
[Test]
public void TestEventsNoValuesToObservable()
{
// start the ProxyService on just one cluster node
IInvocationService invocationService = RestartProxy(null);

// put data items into inner cache to generate events
INamedCache testCache = GetCache("proxy-stop-test");
testCache.Clear();
IDictionary dict = new Hashtable();
for (int i = 0; i < SOME_DATA; i++)
{
dict.Add("TestKey" + i, i);
}
testCache.InsertAll(dict);

// create listener for CQC
ValidateLiteListener listener = new ValidateLiteListener(SOME_DATA);

// instantiate the CQC, will start the test running.
ContinuousQueryCache queryCache = new ContinuousQueryCache(() => testCache, AlwaysFilter.Instance, false, listener, null);
theCQC = queryCache;
Assert.IsFalse(queryCache.CacheValues);

// add standard (non-lite) listener
TestCQCListener listenerStandard = new TestCQCListener(SOME_DATA);
bool isLite = false;
queryCache.AddCacheListener(listenerStandard, AlwaysFilter.Instance, isLite);
Assert.IsTrue(queryCache.CacheValues);
}

/**
* utility method to stop and restart the proxy.
*/
Expand Down Expand Up @@ -264,6 +370,129 @@ public void ResetActualTotal()
}


// ----- data members -----------------------------------------------

/**
* Number of insert events actually received
*/
int m_cActualInserts;

/**
* Number of update events actually received
*/
int m_cActualUpdates;

/**
* Number of delete events actually received
*/
int m_cActualDeletes;

/**
* Number of events listener should receive
*/
int m_cCount;
}
#endregion

// ----- inner class: ValidateLiteListener --------------------------------------

/**
* MapListener that continuously receives events from the cache.
*/
#region Helper class

class ValidateLiteListener : ICacheListener
{

public ValidateLiteListener(int count)
{
m_cCount = count;
m_cActualInserts = 0;
m_cActualUpdates = 0;
m_cActualDeletes = 0;
}

public int Count
{
get { return m_cCount; }
set { m_cCount = value; }
}

/**
* Number of insert events listener actually received.
*
* @return number of event received
*/
public int ActualInserts
{
get { return m_cActualInserts; }
set { m_cActualInserts = value; }
}

/**
* Number of update events listener actually received.
*
* @return number of event received
*/
public int ActualUpdates
{
get { return m_cActualUpdates; }
set { m_cActualUpdates = value; }
}

/**
* Number of delete events listener actually received.
*
* @return number of event received
*/
public int ActualDeletes
{
get { return m_cActualDeletes; }
set { m_cActualDeletes = value; }
}

public void EntryUpdated(CacheEventArgs evt)
{
m_cActualUpdates++;
Assert.AreEqual(evt.NewValue, null);
Assert.AreEqual(evt.OldValue, null);
}

public void EntryInserted(CacheEventArgs evt)
{
m_cActualInserts++;
Assert.AreEqual(evt.NewValue, null);
Assert.AreEqual(evt.OldValue, null);
}

public void EntryDeleted(CacheEventArgs evt)
{
m_cActualDeletes++;
Assert.AreEqual(evt.OldValue, null);
}

/**
* Total number of events listener actually received.
*
* @return number of event received
*/
public int GetActualTotal()
{
return m_cActualInserts+m_cActualUpdates+m_cActualDeletes;
}

/**
* Reset the number of events received.
*
*/
public void ResetActualTotal()
{
m_cActualUpdates = 0;
m_cActualInserts = 0;
m_cActualDeletes = 0;
}


// ----- data members -----------------------------------------------

/**
Expand Down
Loading

0 comments on commit 3d1b238

Please sign in to comment.