gpt4 book ai didi

ColdFusion 变量竞争条件?

转载 作者:行者123 更新时间:2023-12-01 04:56:21 25 4
gpt4 key购买 nike

我想要一些帮助来确定为什么这个特定的代码在极少数情况下会产生竞争条件。我找到了一个修复程序,我也会概述,但我真的很想理解它。

我们有一个基于 CMS 的系统,由许多松散地基于 fusebox 模型的模块组成。一切都通过一个 index.cfm 运行。

在我们的 Index.cfm 中,我们创建了几个组件实例,其中一些基于 Application.cfc 中创建的 APPLICATION.PortalApp 实例。我不包括该代码,因为它并不完全相关:

<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()) />

在我们实例化这些对象之后,我们通过调用作为应用程序的一部分实例化的 PageManager 组件 Application.PortalApp 来获取页面上模块的内容(基于它们的“ Pane ”:顶部、左侧、中间、右侧)。
<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 范围内。

为了解决这个问题,我们将代码更改为以下内容:
<!--- 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 的一部分存在之外。

这在得到报告后很难重现。我基本上开始了一个 jmeter session ,并根据我知道会用 VARIABLES.Module 触发的条件设置断点,尽可能用力地锤击开发服务器。Module 已损坏。这是重现它的唯一方法。

我也不是 100% 确定此修复程序有效,但到目前为止,jmeter 还没有触发条件。

编辑:每个请求,DisplayContent 功能:
<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>

最佳答案

在 PageManager 组件的 DisplayContent 函数中使用 VARIABLES 范围(它被实例化为应用程序的一部分,因此被共享)是问题所在。在这种情况下,将共享 VARIABLES 范围,从而导致竞争条件。

除了在另一个组件中复制该函数并在 index.cfm 的 VARIABLES 范围内实例化它之外,您还可以从 DisplayContent 函数中的 VARIABLES 范围切换到 LOCAL 范围(假设您不需要在功能)。在使用 jmeter 进行压力测试时,这两种方式都可以防止竞争条件再次出现。

关于ColdFusion 变量竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36942015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com