ColdFusion变量种族条件? [英] ColdFusion VARIABLES Race Condition?

查看:243
本文介绍了ColdFusion变量种族条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些帮助,确定为什么这个特殊的代码,在极少数情况下,产生竞争条件。我找到了一个解决方案,我也将概述,但我真的想理解它。

I would like some help identifying why this particular code, in rare circumstances, produces a race condition. I've found a fix, which I'll outline as well, but I really want to understand it.

我们有一个基于CMS的系统,包括许多模块松散关闭保险丝盒模型。

We have a CMS based system comprised of many modules loosely based off a fusebox model. Everything runs through a single index.cfm.

在我们的Index.cfm中,我们创建了几个组件实例,其中一些实例在应用程序中创建的APPLICATION.PortalApp实例上创建.cfc。我不包含该代码,因为它不完全相关:

In our Index.cfm we are creating a couple instances of Components, some are bsaed on the APPLICATION.PortalApp instance created in Application.cfc. I'm not including that code because it's not entirely relevant:

<cfset REQUEST.ActionHandler = CreateObject("Component", "Components.ActionHandler").init(APPLICATION.PortalApp.Config) />
<cfset VARIABLES.Modules = CreateObject("Component", "Components.Modules").init(APPLICATION.PortalApp.Config, REQUEST.ActionHandler.GetModuleList(), REQUEST.ActionHandler.GetSuppressOutput(), REQUEST.ActionHandler.GetRoleList(), REQUEST.ActionHandler.GetAccessList(), REQUEST.ActionHandler.GetMasterRoleList()) />

在我们实例化这些对象之后,我们获取页面上模块的内容(基于它们的'通过调用作为应用程序Application.PortalApp的一部分实例化的PageManager组件,可以调用一个窗格(顶部,左侧,中间,右侧)。

After we instantiate these objects, we get the content for the modules on the page (based on their 'pane': top, left, middle, right) by calling a PageManager component that's instantiated as part of the application, Application.PortalApp.

<cfsavecontent variable="Variables.Portal_Content.Top"><cfset APPLICATION.PortalApp.PageManager.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 0  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Left"><cfset APPLICATION.PortalApp.PageManager.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 1  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Middle"><cfset APPLICATION.PortalApp.PageManager.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 2  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Right"><cfset APPLICATION.PortalApp.PageManager.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 3  ) /></cfsavecontent>

PageManager.DisplayContent基本上循环遍历模块并将它们包装在包装器中。然而,在某些点上,存在竞争条件,并且函数缩放并且根本没有显示模块。它似乎是基于VARIABLES.Modules变得腐败,但是在VARIABLES范围,这是不共享的。

PageManager.DisplayContent basically loops over the modules and wraps them in a wrapper. However, at some points, there is a race condition and the function craters and displays no module at all. It seems to be based on VARIABLES.Modules becoming corrupt but that's in the VARIABLES scope which is not shared.

为了解决它,我们将代码更改为: / p>

To fix it, we changed the code to the following:

<!--- If we do not use VARIABLES scope and create a ContentManager, race condition can cause empty modules --->
<cfset VARIABLES.CurrPageMgr = CreateObject("Component", "Components.ContentManager").init() />

<cfsavecontent variable="Variables.Portal_Content.Top"><cfset VARIABLES.CurrPageMgr.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 0  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Left"><cfset VARIABLES.CurrPageMgr.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 1  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Middle"><cfset VARIABLES.CurrPageMgr.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 2  ) /></cfsavecontent>
<cfsavecontent variable="Variables.Portal_Content.Right"><cfset VARIABLES.CurrPageMgr.DisplayContent( SESSION, REQUEST.ActionHandler, VARIABLES.Modules, 3  ) /></cfsavecontent>

ContentManager的DisplayContent是与PageManager.DisplayContent完全相同的函数文本,ContentManager现有例外只有在VARIABLES范围和PageManager作为APPLICATION的一部分存在。

The DisplayContent of ContentManager is the exact same function text as the PageManager.DisplayContent with the exception on ContentManager existing only in VARIABLES scope and PageManager existing as part of the APPLICATION.

获取报告后很难再现。我基本上启动了一个jmeter会话,尽可能地打破了开发服务器,基于一个条件我设置了一个断点,我知道会使用VARIABLES.Module被破坏。这是重现它的唯一方法。

This was very hard to reproduce after getting reports of it. I essentially started a jmeter session hammering the Development server as hard as possible with a breakpoint set based on a condition I knew would fire with VARIABLES.Module got corrupt. That was the only way to reproduce it.

我也不是100%肯定这个修复工作,但到目前为止jmeter没有解雇它的条件。

I'm also not 100% sure this fix works, but so far jmeter has not fired the condition with it in place.

编辑:按请求,DisplayContent函数:

Per Request, DisplayContent function:

<cffunction name="displayContent" access="public" output="true">
    <cfargument name="SessionData" required="yes" type="Struct" />
    <cfargument name="ActionHandler" required="yes" type="ActionHandler" />
    <cfargument name="Modules" required="yes" type="Modules" />
    <cfargument name="Pane" required="yes" type="numeric" />
    <cfswitch expression="#Arguments.Pane#">
        <cfcase value="1"><cfset Variables.blnPane = ARGUMENTS.Modules.getLeft()></cfcase>
        <cfcase value="2"><cfset Variables.blnPane = ARGUMENTS.Modules.getCenter()></cfcase>
        <cfcase value="3"><cfset Variables.blnPane = ARGUMENTS.Modules.getRight()></cfcase>
        <cfdefaultcase><cfset Variables.blnPane = ARGUMENTS.Modules.getTop()></cfdefaultcase>
    </cfswitch>
    <cfif VARIABLES.blnPane>
        <cfset VARIABLES.qryPaneModules = ARGUMENTS.Modules.GetModulesInPane(Arguments.Pane)>
        <cfset VARIABLES.aryModulesInPane = ArrayNew(1)>
        <cfloop query="VARIABLES.qryPaneModules">
            <cfset VARIABLES.blnResult = ArrayAppend(aryModulesInPane,VARIABLES.qryPaneModules.MOD_SYS_NR)>
        </cfloop>
        <cfset VARIABLES.Template = "../CustomTags/Portalv#ARGUMENTS.SessionData.intPortalVersion#/DisplayModuleAlternate.cfm">
        <cfif Arguments.ActionHandler.GetDocumentType() EQ 3>
            <cfset VARIABLES.Template = "../CustomTags/Portalv#ARGUMENTS.SessionData.intPortalVersion#/DisplayXMLModule.cfm">
        </cfif>
        <cfif VARIABLES.qryPaneModules.recordcount GT 0>
            <cfloop index="VARIABLES.modLoop" from="1" to="#ArrayLen(VARIABLES.aryModulesInPane)#">
                <cfparam name="VARIABLES.aryModulesInPane[VARIABLES.modLoop]" default="0">
                <cfset VARIABLES.objModuleInfo = ARGUMENTS.Modules.GetModuleInfo( VARIABLES.aryModulesInPane[VARIABLES.modLoop], ARGUMENTS.Modules.GetModules() ) />
                <cfif NOT IsNumeric(VARIABLES.objModuleInfo.intModuleID)>
                    <cfset VARIABLES.objModuleInfo.intModuleID = 0 >
                </cfif>
                <cfmodule template="#VARIABLES.Template#"
                    ModuleID="#VARIABLES.objModuleInfo.intModuleID#"
                    ModuleName="#VARIABLES.objModuleInfo.strModuleName#"
                    SecurityLevel="#VARIABLES.objModuleInfo.intRoleTypeID#"
                    ModuleDSN="#VARIABLES.objModuleInfo.strModDBDSN#"
                    ModuleUserName="#VARIABLES.objModuleInfo.strModDBUserID#"
                    ModulePassword="#VARIABLES.objModuleInfo.strModDBPassword#"
                    AlternateFunctionID="#VARIABLES.objModuleInfo.intAlternateFunctionID#"
                    AlternateFunctionName="#VARIABLES.objModuleInfo.strAlternateFunctionName#"
                    InstructionFileID="#VARIABLES.objModuleInfo.intManualID#"
                    ModuleOps="#VARIABLES.objModuleInfo.blnModuleOps#"
                    ModuleSource="#VARIABLES.objModuleInfo.strModuleSource#"
                    ItemID="#VARIABLES.objModuleInfo.intModItemID#"
                    AutoLoginID="#VARIABLES.objModuleInfo.intAutoLoginCategoryID#"
                    IPS_objPortalSessionData="#ARGUMENTS.SessionData#"
                    ModuleList="#ARGUMENTS.ActionHandler.GetModuleList_SingleRecord(VARIABLES.objModuleInfo.intModuleID)#"
                    ModulesComponent="#ARGUMENTS..Modules#"
                    ControlHeaderIR = "#VARIABLES.objModuleInfo.blnControlHeaderIR#"
                    BorderIR = "#VARIABLES.objModuleInfo.blnBorderIR#"
                    IPS_strPortalRoot = "#VARIABLES.IPS_strPortalRoot#"
                    IPS_strPortalURL = "#VARIABLES.IPS_strPortalURL#"
                    Wrapper = "#Arguments.ActionHandler.getWrapper()#"
                    Definition = "#VARIABLES.objModuleInfo.strModuleDef#"
                    Category = "#VARIABLES.objModuleInfo.strModuleCat#"
                    aryModulesInPane = "#VARIABLES.aryModulesInPane#"
                    blnLockIR = "#VARIABLES.objModuleInfo.blnLockIR#"
                    strMessageTE = "#VARIABLES.objModuleInfo.strMessageTE#" >

            </cfloop>
        </cfif>
    </cfif>
</cffunction>


推荐答案

在DisplayContent函数中使用VARIABLES作用域PageManager组件(被实例化为应用程序的一部分,因此被共享)是问题。

Use of the VARIABLES scope inside the DisplayContent function of the PageManager component (which was instantiated as part of the Application, thus shared), was the issue. The VARIABLES scope would be shared in this case leading to race conditions.

除了在另一个组件中复制该函数,并在index.cfm的VARIABLES范围内进行实例化之外,VARIABLES作用域将被共享,您还可以从DisplayContent函数中的VARIABLES范围切换到LOCAL范围(假设您不需要访问函数外的这些变量)。当使用jmeter进行压力测试时,两种方式都保持了竞态条件不会重新出现。

Outside of duplicating that function in another component and instantiating it in the VARIABLES scope of the index.cfm, you could also switch from the VARIABLES scope in the DisplayContent function to the LOCAL scope (assuming you didn't need access to these variables outside the function). Both ways kept the race condition from re-appearing when stress testing with jmeter.

这篇关于ColdFusion变量种族条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆