[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "retry_deux" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Thu Feb 2 17:03:26 CST 2012
branch "retry_deux" has been updated
via 6fc167a116b660eb2cd6cc798976030874fcc29e (commit)
from a2f6d2e757244acc9ca6c0583bc68fb4d52d14f6 (commit)
Summary of changes:
.../AsteriskSCF/Helpers/OperationContextCache.h | 20 ++++
src/Helpers/OperationContextCache.cpp | 108 +++++++++++++++-----
.../OperationContextCacheTest.cpp | 22 +++-
3 files changed, 119 insertions(+), 31 deletions(-)
- Log -----------------------------------------------------------------
commit 6fc167a116b660eb2cd6cc798976030874fcc29e
Author: Ken Hunt <ken.hunt at digium.com>
Date: Thu Feb 2 17:02:57 2012 -0600
Incorporated review feedback.
diff --git a/include/AsteriskSCF/Helpers/OperationContextCache.h b/include/AsteriskSCF/Helpers/OperationContextCache.h
index 77207c2..a3a50f9 100644
--- a/include/AsteriskSCF/Helpers/OperationContextCache.h
+++ b/include/AsteriskSCF/Helpers/OperationContextCache.h
@@ -20,6 +20,7 @@
#include <IceUtil/Timer.h>
#include <AsteriskSCF/System/OperationsIf.h>
+#include <AsteriskSCF/Logger.h>
namespace AsteriskSCF
{
@@ -42,6 +43,19 @@ public:
* remain in cache longer.
*/
OperationContextCache(int ttlSeconds);
+
+ /**
+ * ctor for logging.
+ * @param ttlSeconds The time-to-live for the OperationContexts being cached.
+ * Entries will remain in the cache for at least the provided value, but can
+ * remain in cache longer.
+ * @param logger The logger to log to.
+ * @param label Label to apply when logging to identify this cache.
+ */
+ OperationContextCache(int ttlSeconds,
+ const AsteriskSCF::System::Logging::Logger& logger,
+ const std::string& label);
+
~OperationContextCache();
/**
@@ -70,6 +84,12 @@ public:
std::size_t size();
private:
+ bool containsImpl(const AsteriskSCF::System::V1::OperationContextPtr& operationContext);
+ void logStaleList(std::vector<std::string>& staleList);
+
+ AsteriskSCF::System::Logging::Logger mLogger;
+ bool mLoggingEnabled;
+ std::string mLoggingLabel;
boost::shared_mutex mLock;
IceUtil::TimerTaskPtr mTimerTask;
IceUtil::TimerPtr mTimer;
diff --git a/src/Helpers/OperationContextCache.cpp b/src/Helpers/OperationContextCache.cpp
index b71ba1d..888fc63 100644
--- a/src/Helpers/OperationContextCache.cpp
+++ b/src/Helpers/OperationContextCache.cpp
@@ -18,6 +18,12 @@
#include <AsteriskSCF/Helpers/OperationContextCache.h>
using namespace AsteriskSCF::System::V1;
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+Logger lg = AsteriskSCF::System::Logging::getLoggerFactory().getLogger("AsteriskSCF.Helpers");
+}
namespace AsteriskSCF
{
@@ -27,7 +33,7 @@ namespace Helpers
/**
* Wrapper to hold OperationContext with a timestamp in the cache.
*/
-class OperationContextCachEntry : IceUtil::Shared
+class OperationContextCachEntry : public IceUtil::Shared
{
public:
/**
@@ -97,7 +103,31 @@ typedef IceUtil::Handle<OperationContextPruner> OperationContextPrunerPtr;
* may be cached longer.
*/
OperationContextCache::OperationContextCache(int ttlSeconds)
- : mTTL(IceUtil::Time::seconds(ttlSeconds)),
+ : mLogger(lg),
+ mLoggingEnabled(false),
+ mLoggingLabel(""),
+ mTTL(IceUtil::Time::seconds(ttlSeconds)),
+ mTimer(new IceUtil::Timer),
+ mTimerTask(new OperationContextPruner(this))
+{
+ mTimer->scheduleRepeated(mTimerTask, mTTL);
+}
+
+/**
+ * Alternate constructor that enables logging.
+ * @param ttlSeconds The time to live for the cache, specified in seconds.
+ * This is a minimum time for an OperationContext to be cached. They
+ * may be cached longer.
+ * @param logger Logger to use.
+ * @param label Label to apply when logging to identify this cache.
+ */
+OperationContextCache::OperationContextCache(int ttlSeconds,
+ const Logger& logger,
+ const std::string& label)
+ : mLogger(logger),
+ mLoggingEnabled(true),
+ mLoggingLabel(label),
+ mTTL(IceUtil::Time::seconds(ttlSeconds)),
mTimer(new IceUtil::Timer),
mTimerTask(new OperationContextPruner(this))
{
@@ -110,20 +140,33 @@ OperationContextCache::~OperationContextCache()
}
/**
+ * Non-locking contains() operation for code sharing.
+ */
+bool OperationContextCache::containsImpl(const OperationContextPtr& operationContext)
+{
+ std::map<std::string, OperationContextCachEntryPtr>::iterator entry = mCache.find(operationContext->id);
+ if (entry == mCache.end())
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
* Caches the specified context if it isnt' already in the cache.
* @return true The context was added, which means it wasn't already in the cache.
* @note Make sure you don't confuse the return value of this operation with the return
* value of the 'contains' operation.
*/
-bool OperationContextCache::addOperationContext(const AsteriskSCF::System::V1::OperationContextPtr& operationContext)
+bool OperationContextCache::addOperationContext(const OperationContextPtr& operationContext)
{
- if (contains(operationContext))
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+
+ if (containsImpl(operationContext))
{
return false;
}
- boost::unique_lock<boost::shared_mutex> lock(mLock);
-
OperationContextCachEntryPtr entry(new OperationContextCachEntry(operationContext, mTTL));
mCache[operationContext->id] = entry;
@@ -134,16 +177,22 @@ bool OperationContextCache::addOperationContext(const AsteriskSCF::System::V1::O
* Tests if the specified context is in the cache.
* @param operationContext
*/
-bool OperationContextCache::contains(const AsteriskSCF::System::V1::OperationContextPtr& operationContext)
+bool OperationContextCache::contains(const OperationContextPtr& operationContext)
{
- boost::unique_lock<boost::shared_mutex> lock(mLock);
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
- std::map<std::string, OperationContextCachEntryPtr>::iterator entry = mCache.find(operationContext->id);
- if (entry == mCache.end())
+ return containsImpl(operationContext);
+}
+
+void OperationContextCache::logStaleList(std::vector<std::string>& staleList)
+{
+ mLogger(Trace) << "Purging OperationContextCache " << mLoggingLabel << " of " << staleList.size() << " items:";
+
+ std::vector<std::string>::const_iterator staleIter;
+ for (staleIter = staleList.begin(); staleIter != staleList.end(); staleIter++)
{
- return false;
+ mLogger(Trace) << " " << mLoggingLabel << ": Pruning Operation Id " << (*staleIter);
}
- return true;
}
/**
@@ -151,33 +200,40 @@ bool OperationContextCache::contains(const AsteriskSCF::System::V1::OperationCon
*/
void OperationContextCache::prune()
{
- boost::unique_lock<boost::shared_mutex> lock(mLock);
+ std::vector<std::string> staleList;
+ { // lock scope
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
- std::map<std::string, OperationContextCachEntryPtr>::const_iterator cacheIter;
+ std::map<std::string, OperationContextCachEntryPtr>::const_iterator cacheIter;
- IceUtil::Time now(IceUtil::Time::now());
- std::vector<std::string> staleList;
+ IceUtil::Time now(IceUtil::Time::now());
- // Build list of stale items.
- for(cacheIter = mCache.begin(); cacheIter != mCache.end(); cacheIter++)
- {
- if (cacheIter->second->isStale(now))
+ // Build list of stale item ids.
+ for(cacheIter = mCache.begin(); cacheIter != mCache.end(); cacheIter++)
+ {
+ if (cacheIter->second->isStale(now))
+ {
+ staleList.push_back(cacheIter->first);
+ }
+ }
+
+ // Drop the stale items from the cache.
+ std::vector<std::string>::const_iterator staleIter;
+ for (staleIter = staleList.begin(); staleIter != staleList.end(); staleIter++)
{
- staleList.push_back(cacheIter->first);
+ mCache.erase(*staleIter);
}
}
- // Drop the stale items from the cache.
- std::vector<std::string>::const_iterator purgeIter;
- for (purgeIter = staleList.begin(); purgeIter != staleList.end(); purgeIter++)
+ if (mLoggingEnabled)
{
- mCache.erase(*purgeIter);
+ logStaleList(staleList);
}
}
std::size_t OperationContextCache::size()
{
- boost::unique_lock<boost::shared_mutex> lock(mLock);
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
return mCache.size();
}
diff --git a/test/OperationContextCache/OperationContextCacheTest.cpp b/test/OperationContextCache/OperationContextCacheTest.cpp
index 266590d..1f2822e 100644
--- a/test/OperationContextCache/OperationContextCacheTest.cpp
+++ b/test/OperationContextCache/OperationContextCacheTest.cpp
@@ -16,7 +16,10 @@
#include <Ice/Properties.h>
#include <Ice/Initialize.h>
+
#include <AsteriskSCF/Helpers/OperationContextCache.h>
+#include <AsteriskSCF/Logger.h>
+
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <string>
@@ -27,10 +30,16 @@
using namespace AsteriskSCF;
using namespace AsteriskSCF::System::V1;
using namespace AsteriskSCF::Helpers;
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+Logger lg = AsteriskSCF::System::Logging::getLoggerFactory().getLogger("TestMyLogOutput");
+}
static void testCache(const OperationContextCachePtr& cache, std::vector<OperationContextPtr>& expected)
{
- BOOST_CHECK(cache->size() == expected.size());
+ BOOST_CHECK_MESSAGE(cache->size() == expected.size(), "testCache failed: Cache size=" << cache->size() << ", expected " << expected.size());
for(int i=0; i < expected.size(); ++i)
{
@@ -40,9 +49,11 @@ static void testCache(const OperationContextCachePtr& cache, std::vector<Operati
static void runOperationContextCacheTest()
{
+ lg.setLevel(Trace);
+
const int TTL_SECONDS(5);
- OperationContextCachePtr cache = new OperationContextCache(TTL_SECONDS);
+ OperationContextCachePtr cache = new OperationContextCache(TTL_SECONDS, lg, "TestCache");
std::vector<OperationContextPtr> testOperations;
// Verify empty
@@ -62,8 +73,10 @@ static void runOperationContextCacheTest()
// Make sure it rejets duplicates.
BOOST_CHECK(cache->addOperationContext(testOperations[0]) == false);
- // Make sure the cache purges as intended. Twice the TTL is worst case.
- IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(2*TTL_SECONDS));
+ // Make sure the cache purges as intended. Twice TTL should be the worst case.
+ // But TimerTask doesn't seem to fire at a very precise time, so fudge it or
+ // you get erratic test results.
+ IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(2.5*TTL_SECONDS));
testOperations.clear();
@@ -71,7 +84,6 @@ static void runOperationContextCacheTest()
testCache(cache, testOperations);
testOperations.clear();
-
}
using namespace boost::unit_test;
-----------------------------------------------------------------------
--
asterisk-scf/integration/ice-util-cpp.git
More information about the asterisk-scf-commits
mailing list