Преглед изворни кода

Merge pull request #10592 from wangkx/h18281a

HPCC-18281 Upgrade ESP Paging cache

Reviewed-By: Jake Smith <jake.smith@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman пре 7 година
родитељ
комит
7b7c05b088

+ 38 - 12
dali/base/dautils.cpp

@@ -1912,11 +1912,23 @@ IRemoteConnection *getSortedElements( const char *basexpath,
 //==================================================================================
 
 #define PAGE_CACHE_TIMEOUT (1000*60*10)
+#define MAX_PAGE_CACHE_ITEMS 1000
+static unsigned pageCacheTimeoutMilliSeconds = PAGE_CACHE_TIMEOUT;
+void setPageCacheTimeoutMilliSeconds(unsigned timeoutSeconds)
+{
+    pageCacheTimeoutMilliSeconds = 1000 * timeoutSeconds;
+}
+
+static unsigned maxPageCacheItems = MAX_PAGE_CACHE_ITEMS;
+void setMaxPageCacheItems(unsigned _maxPageCacheItems)
+{
+    maxPageCacheItems = _maxPageCacheItems;
+}
 
 class CTimedCacheItem: public CInterface
 {
 protected: friend class CTimedCache;
-    unsigned due;
+    unsigned due = 0;
     StringAttr owner;
 public:
     DALI_UID hint;
@@ -1924,7 +1936,6 @@ public:
         : owner(_owner)
     {
         hint = queryCoven().getUniqueId();
-        due = msTick()+PAGE_CACHE_TIMEOUT;
     }
 };
 
@@ -1949,16 +1960,26 @@ class CTimedCache
 
     unsigned check()
     {
+        /* The items are ordered, such that oldest items are at the start.
+        This method scans through from oldest to newest until the current
+        item's "due" time has not expired. It then removes all up to that
+        point, i.e. those that have expired, and returns the timing 
+        difference between now and the next due time. */
+        unsigned expired = 0;
         unsigned res = (unsigned)-1;
         unsigned now = msTick();
-        ForEachItemInRev(i,items) {
+        ForEachItemIn(i, items)
+        {
             CTimedCacheItem &item = items.item(i);
-            unsigned t = item.due-now;
-            if ((int)t<=0)
-                items.remove(i);
-            else if (t<res)
-                res = t;
+            if (item.due > now)
+            {
+                res = item.due - now;
+                break;
+            }
+            expired++;
         }
+        if (expired > 0)
+            items.removen(0, expired);
         return res;
     }
 
@@ -1998,7 +2019,9 @@ public:
         if (!item)
             return 0;
         CriticalBlock block(sect);
-        item->due = msTick()+PAGE_CACHE_TIMEOUT;
+        if ((maxPageCacheItems > 0) && (maxPageCacheItems == items.length()))
+            items.remove(0);
+        item->due = msTick() + pageCacheTimeoutMilliSeconds;
         items.append(*item);
         DALI_UID ret = item->hint;
         sem.signal();
@@ -2097,15 +2120,17 @@ IRemoteConnection *getElementsPaged( IElementsPager *elementsPager,
 {
     if ((pagesize==0) || !elementsPager)
         return NULL;
+    if (maxPageCacheItems > 0)
     {
         CriticalBlock block(pagedElementsCacheSect);
-        if (!pagedElementsCache) {
+        if (!pagedElementsCache)
+        {
             pagedElementsCache = new CTimedCache;
             pagedElementsCache->start();
         }
     }
     Owned<CPECacheElem> elem;
-    if (hint&&*hint)
+    if (hint && *hint && (maxPageCacheItems > 0))
     {
         elem.setown(QUERYINTERFACE(pagedElementsCache->get(owner,*hint),CPECacheElem)); // NB: removes from cache in process, added back at end
         if (elem)
@@ -2171,7 +2196,8 @@ IRemoteConnection *getElementsPaged( IElementsPager *elementsPager,
     IRemoteConnection *ret = NULL;
     if (elem->conn)
         ret = elem->conn.getLink();
-    if (hint) {
+    if (hint && (maxPageCacheItems > 0))
+    {
         *hint = elem->hint;
         pagedElementsCache->add(elem.getClear());
     }

+ 3 - 0
dali/base/dautils.hpp

@@ -530,4 +530,7 @@ interface ILockInfoCollection : extends IInterface
 extern da_decl ILockInfoCollection *createLockInfoCollection();
 extern da_decl ILockInfoCollection *deserializeLockInfoCollection(MemoryBuffer &mb);
 
+extern da_decl void setPageCacheTimeoutMilliSeconds(unsigned timeoutSeconds);
+extern da_decl void setMaxPageCacheItems(unsigned _maxPageCacheItems);
+
 #endif

+ 7 - 0
esp/services/ws_access/ws_accessService.cpp

@@ -22,6 +22,7 @@
 #include "ws_accessService.hpp"
 #include "exception_util.hpp"
 #include "dasess.hpp"
+#include "dautils.hpp"
 
 #include <set>
 
@@ -176,6 +177,12 @@ void Cws_accessEx::init(IPropertyTree *cfg, const char *process, const char *ser
         m_rawbasedns.append(*onedn.getLink());
     }
 
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
+    if (cfg->hasProp(xpath.str()))
+        setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
+    if (cfg->hasProp(xpath.str()))
+        setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
 }
 
 CLdapSecManager* Cws_accessEx::queryLDAPSecurityManager(IEspContext &context)

+ 8 - 1
esp/services/ws_dfu/ws_dfuService.cpp

@@ -147,7 +147,14 @@ void CWsDfuEx::init(IPropertyTree *cfg, const char *process, const char *service
     if (streq(disableUppercaseTranslation.str(), "true"))
         m_disableUppercaseTranslation = true;
 
-    xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/NodeGroupCacheMinutes", process, service);
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
+    if (cfg->hasProp(xpath.str()))
+        setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
+    if (cfg->hasProp(xpath.str()))
+        setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
+
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/NodeGroupCacheMinutes", process, service);
     int timeout = cfg->getPropInt(xpath.str(), -1);
     if (timeout > -1)
         nodeGroupCacheTimeout = (unsigned) timeout*60*1000;

+ 8 - 1
esp/services/ws_fs/ws_fsService.cpp

@@ -127,7 +127,14 @@ void CFileSprayEx::init(IPropertyTree *cfg, const char *process, const char *ser
         }
     }
 
-    xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/MonitorQueueLabel", process, service);
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
+    if (cfg->hasProp(xpath.str()))
+        setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
+    if (cfg->hasProp(xpath.str()))
+        setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
+
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/MonitorQueueLabel", process, service);
     cfg->getProp(xpath.str(), m_MonitorQueueLabel);
 
     directories.set(cfg->queryPropTree("Software/Directories"));

+ 8 - 0
esp/services/ws_workunits/ws_workunitsService.cpp

@@ -24,6 +24,7 @@
 #include "dalienv.hpp"
 #include "dadfs.hpp"
 #include "daaudit.hpp"
+#include "dautils.hpp"
 #include "exception_util.hpp"
 #include "wujobq.hpp"
 #include "eventqueue.hpp"
@@ -373,6 +374,13 @@ void CWsWorkunitsEx::init(IPropertyTree *cfg, const char *process, const char *s
     VStringBuffer xpath("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/AWUsCacheMinutes", process, service);
     cfg->getPropInt(xpath.str(), awusCacheMinutes);
 
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
+    if (cfg->hasProp(xpath.str()))
+        setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
+    xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
+    if (cfg->hasProp(xpath.str()))
+        setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
+
     xpath.setf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/serverForArchivedECLWU/@netAddress", process, service);
     if (cfg->hasProp(xpath.str()))
     {

+ 14 - 0
initfiles/componentfiles/configxml/esp.xsd.in

@@ -907,6 +907,20 @@
                     </xs:appinfo>
                 </xs:annotation>
             </xs:attribute>
+            <xs:attribute name="PageCacheTimeoutSeconds" type="xs:nonNegativeInteger" use="optional" default="600">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <tooltip>Paging data timeout in the given seconds.</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="MaxPageCacheItems" type="xs:nonNegativeInteger" use="optional" default="1000">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <tooltip>The maximum number of cached items inside one page cache. 0 means no cache.</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
 </xs:schema>