2017-05-23 27 views
0

我需要按请求一次执行一个代码块。用cflock标签包装代码块是不可能的,因为代码运行很长一段时间,因此很容易超时(这是对web服务的调用,需要大量来回)。ColdFusion 11如何一次执行一个代码块

我尝试了以下技术绕过使用CFLOCK标签的:

对于每个请求,我递增应用程序变量(其被初始化为1),并将其分配给它代表的排序中的局部变量请求。

在一个请求完成执行长时间运行的代码后,我增加了另一个应用程序变量(初始化为1)。

因此,对于后续请求,我将它们的排名与后一个应用程序变量进行比较。所以虽然两个值不相等,然后我做一个循环。

下面是代码:

<cflock timeout="1" type="exclusive" throwontimeout="true"> 
    <cfif NOT structKeyExists(APPLICATION,'currentRequestOrder')> 
     <cfset APPLICATION.currentRequestOrder = 1> 
     <cfset APPLICATION.nbRequestsRunning = 1> 
    <cfelse> 
     <cfset APPLICATION.nbRequestsRunning = APPLICATION.nbRequestsRunning + 1> 
    </cfif> 
</cflock> 

<cfset thisRequestOrder = APPLICATION.nbRequestsRunning> 

<cfloop condition="thisRequestOrder NEQ APPLICATION.currentRequestOrder"> 

</cfloop> 

<long running of code> 

</long running of code> 

<cflock timeout="1" type="exclusive" throwontimeout="true"> 
    <cfif APPLICATION.currentRequestOrder LT APPLICATION.nbRequestsRunning> 
     <cfset APPLICATION.currentRequestOrder = APPLICATION.currentRequestOrder + 1> 
    </cfif> 
</cflock> 

这段代码的行为是第一个之后到来的请求没有得到过去的循环。换句话说,cfloop的条件总是评估为真。

我正在寻找的最终解决方案是让每个请求一次执行一次长运行代码。

+3

听起来像XY问题。你描述的内容听起来像是一个排队?也许备份一步并解释a)这个长时间运行的过程(一般而言)和b)为什么它一次只能执行一个请求。 – Leigh

+1

我不明白你为什么不能使用cflock。不要cflock做你想要的东西吗?如果你的代码长时间运行,那么无论你使用什么方法,你都可能会遇到单线程问题。 –

+0

如果要求每个请求只运行一次,那么请拿走您所做的一切来确保这一点。什么都不做就会实现你的目标。嘲笑应用程序变量正在阻止它。 –

回答

0

我们有一个过程会经过一个队列。由于ColdFusion中的内存泄漏,我们不希望它一次处理队列。我们的决议是通过在前一个结束时调用一个新请求来连接请求。

<cfif url.step lt 5> 
    <cfhttp url="#currentTemplate#?step=#url.step+1#" timeout="0" /> 
</cfif> 

或者您可以命名这些步骤。无论哪种方式,这是一种通过将它们分解成步骤来防止长时间运行的请求的方法。您可以将中间数据保存在数据库,应用程序变量等中。