2016-04-29 8 views
4

私はこの特定のコードがまれな状況で競合条件を作り出す理由を特定するのを助けたいと思います。私も概説している修正を見つけましたが、本当に理解したいです。ColdFusionの可変条件

私たちは、ヒューズボックスモデルに基づいている多くのモジュールで構成されるCMSベースのシステムを持っています。すべてが1つのindex.cfmで実行されます。

Index.cfmでは、コンポーネントのインスタンスを2つ作成しています。一部は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を呼び出すことによって、

PageManager.DisplayContentは、基本的にモジュールをループし、ラッパーでラップします。しかし、いくつかの点では競合状態が存在し、この機能はクレーターを持ち、モジュールを全く表示しません。それはVARIABLESに基づいているようです。モジュールは壊れていますが、それは共有されていない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はContentManagerが唯一の変数のスコープとPageManagerの中で、既存の例外を除いてPageManager.DisplayContentとまったく同じ機能のテキストです:

それを修正するには、我々は次のようにコードを変更しましたAPPLICATIONの一部として存在します。

これは、レポートを取得した後に再現するのが非常に困難でした。私は本質的に、私が知っていた状態に基づいて設定されたブレークポイントで可能な限りハードウェアで開発サーバーをハンマーで叩くjmeterセッションを開始しました。それがそれを再現する唯一の方法でした。

私はこの修正プログラムが動作することを100%保証していませんが、これまでのところjmeterは条件を満たしていません。

編集:要求ごと、DisplayContent関数(従って共有アプリケーションの一部としてインスタンス化された)PageManagerの成分の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> 
+1

問題を引き起こしている 'DisplayContent'に何か(スコープされていない変数やロックがないなど)があります。特にリクエストごとに作成すると修正するようです。さらに調査するには 'DisplayContent'コードを見る必要があります。 –

+0

@JohnWhish関数を追加しました... – Brad

+1

そのコンポーネントがアプリケーションスコープに格納されている場合は、その変数スコープに何かを格納することは、基本的にアプリケーションスコープに格納することと同じです。 – Leigh

答えて

1

使用は、問題でした。この場合、範囲の範囲が共有され、競合状態につながります。

他のコンポーネントで機能し、それをindex.cfmのVARIABLESスコープでインスタンス化する以外に、DisplayContent関数のVARIABLESスコープからLOCALスコープに切り替えることもできます。これらの変数は関数外にあります)。 jmeterでストレステストをすると、両方の方法で競合状態が再現されなくなりました。

+1

'variables'スコープへの書き込みはコンポーネント状態* ful *を作成します。これにより、アプリケーションのような共有スコープに格納されたときに競合状態になることがあります。通常、ステートレスコンポーネントのみを共有スコープに格納する必要があります。 state * ful *コンポーネントの場合、通常、別の要求レベルのインスタンスを作成して、変数が他の要求と共有/アクセスできないようにする必要があります。 – Leigh