[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