Browse Source

Merge pull request #6116 from wangkx/h11637a

HPCC-11637 Avoid multiple concourrent ECLWatch onActivity queries

Reviewed-By: Gavin Halliday <gavin.halliday@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 years ago
parent
commit
2c34bd3b29

+ 30 - 7
esp/eclwatch/ws_XSLT/index.xslt

@@ -110,32 +110,35 @@
                                 document.location.href = "/WsSmc/Activity?SortBy=Name";
                         }
 
-                        function commandQueue(action,cluster,clusterType,queue,wuid)
+                        function commandQueue(action,cluster,clusterType,queue,wuid,serverType,ip,port)
                         {
                             document.getElementById("ClusterType").value=clusterType;
                             document.getElementById("Cluster").value=cluster;
                             document.getElementById("QueueName").value=queue;
                             document.getElementById("Wuid").value=wuid || '';
+                            document.getElementById("ServerType").value=serverType;
+                            document.getElementById("NetworkAddress").value=ip;
+                            document.getElementById("Port").value=port;
                             document.forms["queue"].action='/WsSMC/'+action;
                             document.forms["queue"].submit();
                         }
 
                         var oMenu;
 
-                        function queuePopup(cluster,clusterType,queue,paused,stopped,q_rowid)
+                        function queuePopup(cluster,clusterType,queue,serverType,ip,port,paused,stopped,q_rowid)
                         {
                             function clearQueue()
                             {
                                 if(confirm('Do you want to clear the queue for cluster: '+cluster+'?'))
-                                    commandQueue("ClearQueue",cluster,clusterType,queue);
+                                    commandQueue("ClearQueue",cluster,clusterType,queue,'',serverType,ip,port);
                             }
                             function pauseQueue()
                             {
-                                commandQueue("PauseQueue",cluster,clusterType,queue);
+                                commandQueue("PauseQueue",cluster,clusterType,queue,'',serverType,ip,port);
                             }
                             function resumeQueue()
                             {
-                                commandQueue("ResumeQueue",cluster,clusterType,queue);
+                                commandQueue("ResumeQueue",cluster,clusterType,queue,'',serverType,ip,port);
                             }
                             function showUsage()
                             {
@@ -566,6 +569,9 @@
                     <input type="hidden" name="Cluster" id="Cluster" value=""/>
                     <input type="hidden" name="QueueName" id="QueueName" value=""/>
                     <input type="hidden" name="Wuid" id="Wuid" value=""/>
+                    <input type="hidden" name="ServerType" id="ServerType" value=""/>
+                    <input type="hidden" name="NetworkAddress" id="NetworkAddress" value=""/>
+                    <input type="hidden" name="Port" id="Port" value=""/>
                     <xsl:for-each select="ThorClusterList/TargetCluster">
                         <xsl:call-template name="show-queue">
                             <xsl:with-param name="workunits" select="//Running/ActiveWorkunit[(Server='ThorMaster' and TargetClusterName=current()/ClusterName) or (ClusterType='Thor' and ClusterQueueName=current()/QueueName)]"/>
@@ -577,6 +583,7 @@
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
                             <xsl:with-param name="warning" select="Warning"/>
                             <xsl:with-param name="thorlcr" select="ThorLCR"/>
+                            <xsl:with-param name="serverType" select="'ThorMaster'"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -590,6 +597,7 @@
                             <xsl:with-param name="clusterStatus" select="ClusterStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
                             <xsl:with-param name="warning" select="Warning"/>
+                            <xsl:with-param name="serverType" select="'RoxieServer'"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -603,6 +611,7 @@
                             <xsl:with-param name="clusterStatus" select="ClusterStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
                             <xsl:with-param name="warning" select="Warning"/>
+                            <xsl:with-param name="serverType" select="'HThorServer'"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -614,6 +623,9 @@
                             <xsl:with-param name="queue" select="QueueName"/>
                             <xsl:with-param name="queueStatus" select="QueueStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
+                            <xsl:with-param name="ip" select="NetworkAddress"/>
+                            <xsl:with-param name="port" select="Port"/>
+                            <xsl:with-param name="serverType" select="ServerType"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -625,6 +637,9 @@
                             <xsl:with-param name="queue" select="QueueName"/>
                             <xsl:with-param name="queueStatus" select="QueueStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
+                            <xsl:with-param name="ip" select="NetworkAddress"/>
+                            <xsl:with-param name="port" select="Port"/>
+                            <xsl:with-param name="serverType" select="ServerType"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -636,6 +651,9 @@
                             <xsl:with-param name="queue" select="QueueName"/>
                             <xsl:with-param name="queueStatus" select="QueueStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
+                            <xsl:with-param name="ip" select="NetworkAddress"/>
+                            <xsl:with-param name="port" select="Port"/>
+                            <xsl:with-param name="serverType" select="ServerType"/>
                         </xsl:call-template>
                     </xsl:for-each>
 
@@ -647,6 +665,7 @@
                             <xsl:with-param name="queue" select="QueueName"/>
                             <xsl:with-param name="queueStatus" select="QueueStatus"/>
                             <xsl:with-param name="statusDetails" select="StatusDetails"/>
+                            <xsl:with-param name="serverType" select="ServerType"/>
                         </xsl:call-template>
                     </xsl:for-each>
                     <xsl:apply-templates select="DFUJobs"/>
@@ -710,6 +729,9 @@
         <xsl:param name="statusDetails" select="''"/>
         <xsl:param name="warning" select="''"/>
         <xsl:param name="thorlcr" select="'0'"/>
+        <xsl:param name="serverType" select="''"/>
+        <xsl:param name="ip" select="''"/>
+        <xsl:param name="port" select="'0'"/>
         <xsl:variable name="showTitle">
             <xsl:choose>
                 <xsl:when test="$clusterType = 'THOR'">1</xsl:when>
@@ -761,8 +783,8 @@
                 <td valign="top">
                     <xsl:if test="$accessRight = 'Access_Full'">
                         <xsl:variable name="popup">return queuePopup('<xsl:value-of select="$cluster"/>','<xsl:value-of select="$clusterType"/>',
-                            '<xsl:value-of select="$queue"/>',<xsl:value-of select="$queueStatus='paused'"/>,
-                            <xsl:value-of select="$queueStatus='stopped'"/>, '<xsl:value-of select="$q_rowid"/>');
+                            '<xsl:value-of select="$queue"/>','<xsl:value-of select="$serverType"/>','<xsl:value-of select="$ip"/>','<xsl:value-of select="$port"/>',
+                            <xsl:value-of select="$queueStatus='paused'"/>,<xsl:value-of select="$queueStatus='stopped'"/>, '<xsl:value-of select="$q_rowid"/>');
                         </xsl:variable>
                         <a id="{$q_rowid}" class="configurecontextmenu" title="Option" onclick="{$popup}">&#160;</a>
                     </xsl:if>
@@ -811,6 +833,7 @@
                             <xsl:when test="$clusterType = 'ROXIE'">RoxieCluster - <xsl:value-of select="$cluster"/></xsl:when>
                             <xsl:when test="$clusterType = 'THOR'">ThorCluster - <xsl:value-of select="$cluster"/></xsl:when>
                             <xsl:when test="$clusterType = 'HTHOR'">HThorCluster - <xsl:value-of select="$cluster"/></xsl:when>
+                            <xsl:when test="$clusterType = 'ECLCCserver' or $clusterType = 'ECLserver'"><xsl:value-of select="$clusterType"/> - <xsl:value-of select="$cluster"/></xsl:when>
                             <xsl:otherwise>
                                 <xsl:value-of select="$clusterType"/> - <xsl:value-of select="$queue"/>
                             </xsl:otherwise>

+ 13 - 1
esp/scm/ws_smc.ecm

@@ -107,6 +107,15 @@ ESPStruct ServerJobQueue
     string ServerType;
     string QueueStatus;
     [min_ver("1.17")] string StatusDetails;
+    [min_ver("1.19")] string NetworkAddress;
+    [min_ver("1.19")] int Port;
+};
+
+ESPstruct [nil_remove] StatusServerInfo
+{
+    ESPstruct TargetCluster TargetClusterInfo;
+    ESPstruct ServerJobQueue ServerInfo;
+    ESParray<ESPstruct ActiveWorkunit> Workunits;
 };
 
 ESPrequest [nil_remove] ActivityRequest
@@ -185,6 +194,9 @@ ESPrequest SMCQueueRequest
     string Cluster;
     string QueueName;
     string Comment;
+    [min_ver("1.19")] string ServerType;
+    [min_ver("1.19")] string NetworkAddress;
+    [min_ver("1.19")] int Port;
 };
 
 
@@ -321,7 +333,7 @@ RoxieControlCmdResponse
     ESParray<ESPstruct RoxieControlEndpointInfo, Endpoint> Endpoints;
 };
 
-ESPservice [noforms, version("1.17"), default_client_version("1.17"), exceptions_inline("./smc_xslt/exceptions.xslt"), use_method_name] WsSMC
+ESPservice [noforms, version("1.19"), default_client_version("1.19"), exceptions_inline("./smc_xslt/exceptions.xslt"), use_method_name] WsSMC
 {
     ESPmethod Index(SMCIndexRequest, SMCIndexResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/index.xslt")] Activity(ActivityRequest, ActivityResponse);

File diff suppressed because it is too large
+ 621 - 956
esp/services/ws_smc/ws_smcService.cpp


+ 71 - 22
esp/services/ws_smc/ws_smcService.hpp

@@ -41,6 +41,17 @@ enum ClusterStatusType
     QueueRunningNotFound = 4
 };
 
+enum WsSMCStatusServerType
+{
+    WsSMCSSTThorLCRCluster = 0,
+    WsSMCSSTRoxieCluster = 1,
+    WsSMCSSTHThorCluster = 2,
+    WsSMCSSTECLagent = 3,
+    WsSMCSSTterm = 4
+};
+
+static const char *WsSMCStatusServerTypeNames[] = { "ThorMaster", "RoxieServer", "HThorServer", "ECLagent" };
+
 class CWsSMCQueue
 {
 public:
@@ -58,15 +69,18 @@ public:
     virtual ~CWsSMCQueue(){};
 };
 
-class CWsSMCTargetCluster
+class CWsSMCTargetCluster : public CInterface
 {
 public:
     ClusterType clusterType;
-    SCMStringBuffer clusterName;
+    StringAttr clusterName;
+    StringAttr queueName;
+    StringAttr queueStatus;
+    StringAttr warning;
+    int clusterSize;
     SCMStringBuffer statusServerName;
     StringBuffer clusterStatus;
     StringBuffer clusterStatusDetails;
-    StringBuffer queueStatus;
     CWsSMCQueue clusterQueue;
     CWsSMCQueue agentQueue;
     CWsSMCQueue serverQueue;
@@ -75,11 +89,31 @@ public:
     virtual ~CWsSMCTargetCluster(){};
 };
 
+struct ActivityInfo : public CInterface, implements IInterface
+{
+    IMPLEMENT_IINTERFACE;
+
+    ActivityInfo() { timeCached.setNow(); };
+    bool isCachedActivityInfoValid(unsigned timeOutSeconds);
+
+    CDateTime timeCached;
+
+    CIArrayOf<CWsSMCTargetCluster> thorTargetClusters;
+    CIArrayOf<CWsSMCTargetCluster> roxieTargetClusters;
+    CIArrayOf<CWsSMCTargetCluster> hthorTargetClusters;
+
+    IArrayOf<IEspActiveWorkunit> aws;
+    IArrayOf<IEspServerJobQueue> serverJobQueues;
+    IArrayOf<IEspDFUJob> DFURecoveryJobs;
+};
+
 class CWsSMCEx : public CWsSMC
 {
     long m_counter;
     CTpWrapper m_ClusterStatus;
-    CWUXMLInfo m_WuidInfo;
+    CriticalSection getActivityCrit;
+    Owned<ActivityInfo> activityInfoCache;
+    unsigned activityInfoCacheSeconds;
 
     StringBuffer m_ChatURL;
     StringBuffer m_Banner;
@@ -117,42 +151,57 @@ public:
 private:
     void addCapabilities( IPropertyTree* pFeatureNode, const char* access, 
                                  IArrayOf<IEspCapability>& capabilities);
-    void addToThorClusterList(IArrayOf<IEspThorCluster>& clusters, IEspThorCluster* cluster, const char* sortBy, bool descending);
-    void addToRoxieClusterList(IArrayOf<IEspRoxieCluster>& clusters, IEspRoxieCluster* cluster, const char* sortBy, bool descending);
-    void addServerJobQueue(double version, IArrayOf<IEspServerJobQueue>& jobQueues, const char* queueName, const char* serverName, const char* serverType);
-    void addServerJobQueue(double version, IArrayOf<IEspServerJobQueue>& jobQueues, const char* queueName, const char* serverName, const char* serverType, const char* queueState, const char* queueStateDetails);
-    void getQueueState(int runningJobsInQueue, StringBuffer& queueState, BulletType& colorType);
-    void readClusterTypeAndQueueName(CConstWUClusterInfoArray& clusters, const char* clusterName, StringBuffer& clusterType, SCMStringBuffer& clusterQueue);
-    void addRunningWUs(IEspContext &context, IPropertyTree& node, CConstWUClusterInfoArray& clusters,
-                   IArrayOf<IEspActiveWorkunit>& aws, BoolHash& uniqueWUIDs,
-                   StringArray& runningQueueNames, int* runningJobsInQueue);
+    void addServerJobQueue(IArrayOf<IEspServerJobQueue>& jobQueues, const char* queueName, const char* serverName,
+        const char* serverType, const char* networkAddress, unsigned port);
+    void addServerJobQueue(IArrayOf<IEspServerJobQueue>& jobQueues, const char* queueName, const char* serverName,
+        const char* serverType, const char* networkAddress, unsigned port, const char* queueState, const char* queueStateDetails);
     void readBannerAndChatRequest(IEspContext& context, IEspActivityRequest &req, IEspActivityResponse& resp);
     void setBannerAndChatData(double version, IEspActivityResponse& resp);
-    void getServersAndWUs(IEspContext &context, IEspActivityRequest &req, IEspActivityResponse& resp, double version,
-        IPropertyTree* envRoot, CConstWUClusterInfoArray& clusters);
+    void getServersAndWUs(IEspContext &context, IEspActivityRequest &req, IPropertyTree* envRoot, CConstWUClusterInfoArray& clusters,
+        ActivityInfo* activityInfo);
 
     void sortTargetClusters(IArrayOf<IEspTargetCluster>& clusters, const char* sortBy, bool descending);
     void createActiveWorkUnit(Owned<IEspActiveWorkunit>& ownedWU, IEspContext &context, const char* wuid, const char* location,
-    unsigned index, const char* serverName, const char* queueName, const char* instanceName, const char* targetClusterName);
+        unsigned index, const char* serverName, const char* queueName, const char* instanceName, const char* targetClusterName, bool useContext);
     void readDFUWUs(IEspContext &context, const char* queueName, const char* serverName, IArrayOf<IEspActiveWorkunit>& aws);
-    void readRunningWUsOnServerNode(IEspContext& context, IPropertyTree& serverStatusNode, const char* targetClusterName,
-         unsigned& runningJobsInQueue, BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
     void readRunningWUsOnECLAgent(IEspContext& context, IPropertyTreeIterator* itStatusECLagent, CConstWUClusterInfoArray& clusters,
          CWsSMCTargetCluster& targetCluster, BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
-    void readWUsAndStateFromJobQueue(IEspContext& context, CWsSMCTargetCluster& targetCluster, CWsSMCQueue& queue, const char* listQueue, IArrayOf<IEspActiveWorkunit>& aws);
+    void readWUsAndStateFromJobQueue(IEspContext& context, CWsSMCTargetCluster& targetCluster, CWsSMCQueue& queue, const char* listQueue, BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
     void addToTargetClusterList(IArrayOf<IEspTargetCluster>& clusters, IEspTargetCluster* cluster, const char* sortBy, bool descending);
-    bool foundQueueInStatusServer(IEspContext& context, IPropertyTree* serverStatusRoot, const char* serverName, const char* processName, const char* processExt);
+    bool findQueueInStatusServer(IEspContext& context, IPropertyTree* serverStatusRoot, const char* serverName, const char* queueName);
     void setClusterQueueStatus(CWsSMCTargetCluster& targetCluster);
     void setClusterStatus(IEspContext& context, CWsSMCTargetCluster& targetCluster, IEspTargetCluster* returnCluster);
     void getTargetClusterAndWUs(IEspContext& context, CConstWUClusterInfoArray& clusters, IConstWUClusterInfo& cluster,
          IPropertyTree* serverStatusRoot, IPropertyTreeIterator* itStatusECLagent, IEspTargetCluster* returnCluster, IArrayOf<IEspActiveWorkunit>& aws);
     void getWUsNotOnTargetCluster(IEspContext &context, IPropertyTree* serverStatusRoot, IArrayOf<IEspServerJobQueue>& serverJobQueues, IArrayOf<IEspActiveWorkunit>& aws);
     void getDFUServersAndWUs(IEspContext &context, IPropertyTree* envRoot, IArrayOf<IEspServerJobQueue>& serverJobQueues, IArrayOf<IEspActiveWorkunit>& aws);
-    void getDFURecoveryJobs(IEspContext &context, IArrayOf<IEspDFUJob>& jobs);
+    void getDFURecoveryJobs(IEspContext &context, const IPropertyTree* dfuRecoveryRoot, IArrayOf<IEspDFUJob>& jobs);
     const char* createQueueActionInfo(IEspContext &context, const char* action, IEspSMCQueueRequest &req, StringBuffer& info);
     void setServerJobQueueStatus(double version, IEspServerJobQueue* jobQueue, const char* status, const char* details);
-};
+    void setServerJobQueueStatus(IEspServerJobQueue* jobQueue, const char* status, const char* details);
+    void setServerJobQueueStatusDetails(IEspServerJobQueue* jobQueue, const char* status, const char* details);
 
+    void readTargetClusterInfo(IEspContext &context, CConstWUClusterInfoArray& clusters, IPropertyTree* serverStatusRoot,
+        ActivityInfo* activityInfo);
+    void readTargetClusterInfo(IEspContext& context, IConstWUClusterInfo& cluster, IPropertyTree* serverStatusRoot, CWsSMCTargetCluster* targetCluster);
+    void readRunningWUsAndQueuedWUs(IEspContext &context, IPropertyTree* envRoot, IPropertyTree* serverStatusRoot,
+        IPropertyTree* dfuRecoveryRoot, ActivityInfo* activityInfo);
+    CWsSMCTargetCluster* findWUClusterInfo(IEspContext& context, const char* wuid, bool isOnECLAgent,
+            CIArrayOf<CWsSMCTargetCluster>& targetClusters, CIArrayOf<CWsSMCTargetCluster>& targetClusters1, CIArrayOf<CWsSMCTargetCluster>& targetClusters2);
+    CWsSMCTargetCluster* findTargetCluster(const char* clusterName, CIArrayOf<CWsSMCTargetCluster>& targetClusters);
+    void readRunningWUsOnStatusServer(IEspContext& context, IPropertyTree* serverStatusRoot, WsSMCStatusServerType statusServerType,
+            CIArrayOf<CWsSMCTargetCluster>& targetClusters, CIArrayOf<CWsSMCTargetCluster>& targetClusters1, CIArrayOf<CWsSMCTargetCluster>& targetClusters2,
+            BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
+    void readWUsAndStateFromJobQueue(IEspContext& context, CWsSMCTargetCluster& targetCluster, BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
+    void readWUsAndStateFromJobQueue(IEspContext& context, CIArrayOf<CWsSMCTargetCluster>& targetClusters, BoolHash& uniqueWUIDs, IArrayOf<IEspActiveWorkunit>& aws);
+    void setESPTargetClusters(IEspContext& context, CIArrayOf<CWsSMCTargetCluster>& targetClusters, IArrayOf<IEspTargetCluster>& respTargetClusters);
+    ActivityInfo* createActivityInfo(IEspContext &context, IEspActivityRequest &req);
+    void clearActivityInfoCache();
+    ActivityInfo* getActivityInfo(IEspContext &context, IEspActivityRequest &req);
+    void setActivityResponse(IEspContext &context, ActivityInfo* activityInfo, IEspActivityRequest &req, IEspActivityResponse& resp);
+    void addWUsToResponse(IEspContext &context, const IArrayOf<IEspActiveWorkunit>& aws, IEspActivityResponse& resp);
+    const char *getStatusServerTypeName(WsSMCStatusServerType type);
+};
 
 class CWsSMCSoapBindingEx : public CWsSMCSoapBinding
 {

+ 6 - 0
esp/services/ws_workunits/WUWrapper.hpp

@@ -39,6 +39,12 @@ public:
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Could not open workunit %s",wuid);
     }
 
+    CWUWrapper(const char* wuid): factory(getWorkUnitFactory()), wu(factory->openWorkUnit(wuid, false))
+    {
+        if(!wu)
+            throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Could not open workunit %s",wuid);
+    }
+
     CWUWrapper(const char * parentWuid, const char * app, const char * user, IEspContext &context): 
         factory(getSecWorkUnitFactory(*context.querySecManager(), *context.queryUser())), wu(factory->createWorkUnit(parentWuid, app, user))
     {

+ 1 - 0
esp/smc/SMCLib/exception_util.hpp

@@ -121,6 +121,7 @@
 #define ECLWATCH_QUERY_SUSPENDED            ECLWATCH_ERROR_START+101
 #define ECLWATCH_PACKAGEMAP_NOTRESOLVED     ECLWATCH_ERROR_START+102
 #define ECLWATCH_RESOURCE_NOT_FOUND         ECLWATCH_ERROR_START+103
+#define ECLWATCH_CANNOT_GET_STATUS_INFO     ECLWATCH_ERROR_START+104
 
 inline void FORWARDEXCEPTION(IEspContext &context, IException *e, unsigned codeNew)
 {

+ 5 - 1
initfiles/componentfiles/configxml/@temp/esp_service_WsSMC.xsl

@@ -137,7 +137,11 @@ This is required by its binding with ESP service '<xsl:value-of select="$espServ
                 <xsl:with-param name="plugin" select="'ws_smc'"/>
             </xsl:call-template>
         </xsl:variable>
-        <EspService name="{$serviceName}" type="{$serviceType}" plugin="{$servicePlugin}"/>
+        <EspService name="{$serviceName}" type="{$serviceType}" plugin="{$servicePlugin}">
+            <xsl:if test="string(@ActivityInfoCacheSeconds) != ''">
+                <ActivityInfoCacheSeconds><xsl:value-of select="@ActivityInfoCacheSeconds"/></ActivityInfoCacheSeconds>
+            </xsl:if>
+        </EspService>
         <EspBinding name="{$bindName}" service="{$serviceName}" protocol="{$bindingNode/@protocol}" type="{$bindType}" 
              plugin="{$servicePlugin}" netAddress="0.0.0.0" port="{$bindingNode/@port}" defaultBinding="true">
             <xsl:call-template name="bindAuthentication">

+ 7 - 0
initfiles/componentfiles/configxml/espsmcservice.xsd

@@ -88,6 +88,13 @@
                     </xs:appinfo>
                 </xs:annotation>
             </xs:attribute>
+            <xs:attribute name="ActivityInfoCacheSeconds" type="xs:nonNegativeInteger" use="optional" default="10">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <tooltip>timeout for activity info cache (in seconds).</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
             <xs:attribute name="enableSystemUseRewrite" type="xs:boolean" use="optional" default="false">
                 <xs:annotation>
                     <xs:appinfo>

+ 7 - 0
initfiles/componentfiles/configxml/espsmcservice.xsd.in

@@ -83,6 +83,13 @@
                     </xs:appinfo>
                 </xs:annotation>
             </xs:attribute>
+            <xs:attribute name="ActivityInfoCacheSeconds" type="xs:nonNegativeInteger" use="optional" default="10">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <tooltip>timeout for activity info cache (in seconds).</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
             <xs:attribute name="serverForArchivedECLWU" type="sashaServerType" use="optional">
                 <xs:annotation>
                     <xs:appinfo>

+ 1 - 0
initfiles/etc/DIR_NAME/environment.xml.in

@@ -599,6 +599,7 @@
   </EspProcess>
   <EspService allowNewRoxieOnDemandQuery="false"
               AWUsCacheTimeout="15"
+              ActivityInfoCacheSeconds="10"
               build="${projname}_${version}-${stagever}"
               buildSet="espsmc"
               description="ESP services for SMC"