我需要每个请求一次执行一个代码块。使用cflock标记包装代码块是不可能的,因为代码运行了很长一段时间,因此容易超时(这是对web服务的调用,需要大量来回)。
我尝试了以下技术来绕过使用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的条件总是评估为真。
我正在寻找的最终解决方案是让每个请求一次执行一次长时间运行的代码。
答案 0 :(得分:0)
我们有一个可以通过队列的进程。由于ColdFusion中的内存泄漏,我们不希望它一次性处理队列。我们的决议是通过在前一个结束时调用一个新请求来链接请求。
<cfif url.step lt 5>
<cfhttp url="#currentTemplate#?step=#url.step+1#" timeout="0" />
</cfif>
或者您可以命名这些步骤。无论哪种方式,这都是一种通过将其分解为步骤来防止长时间运行请求的方法。您可以将中间数据保存在数据库,应用程序变量等中。