7

まず、20CF Adminで(秒)後のタイムアウト要求をに設定しました。

次に、次のような行でcfmを実行しますwhile(true);

ページは20秒を過ぎても実行され、これを書いた時点でスレッドはまだ生きています。

以下は、サーバーモニターで撮影したスナップショットです。

Thread  jrpp-3 request type - TEMPLATE REQUEST
*Template Path - D:\Projects\infiniteLoop.cfm
*Request Parameters - {}
*Request Method - GET
*Client IP address - 127.0.0.1
*Thread elapsed time - 322659 milliseconds

これは正常ですか?これはCF9.0.1、開発者版です。JRunを使用したマルチインスタンスセットアップ。

無限ループを停止する唯一の方法は、CFを再起動することです。

4

3 に答える 3

13

ColdFuisonでのリクエストのタイムアウトは、期待どおりに動作しません。リクエストが実行されている時間をチェックし、リクエストのタイムアウト時またはその直後にそれを強制終了するウォッチドッグがあることを想像してみてください。実際に発生しているように見えるのは、特定のタグが実行された場合にのみ、CFが要求の経過時間が設定された制限を超えているかどうかをチェックすることです。<cfoutput>はチェックするタグの1つです。そのため、実行に時間がかからないことがわかっていても、cfoutputを指すタイムアウト超過メッセージが頻繁に表示されます。

<cfsetting requesttimeout="5" enableCFoutputOnly="no" />

<!--- Looping with a condition <cfloop blamed --->
<cfset request.counter=0 />
<cfloop condition="true">
    <cfset sleep(1000) />
    <cfset request.counter=request.counter+1>

    <cflog file="timeout" text="#request.counter#">

    <cfif request.counter GT 8>
        <cfbreak>
    </cfif>

</cfloop>

<!--- Looping with an index, times out, naming CFLOOP as the offending tag --->
<cfloop index="foo" from="1" to="8">
    <cfset sleep(1000) />
</cfloop>

<!--- Looping with an index, times out, naming CFOUTPUT as the offending tag --->
<cfloop index="foo" from="1" to="8">
    <cfset sleep(1000) />
    <cfoutput>Hello</cfoutput>
</cfloop>


<!--- Same loop, but in script. No timeout warning at all --->
<cfscript>
for(foo=1;foo<=8;foo++){
    sleep(1000);
}
</cfscript>

<!--- Same loop, now with WriteOutput() called. Still no timeout --->
<cfscript>
for(foo=1;foo<=8;foo++){
    sleep(1000);
    writeoutput("tick...");
}
</cfscript>

上記のコードは、requesttimeoutの奇妙な動作の一部を示しています。Mark Krugerが指摘したように、外部リソースへの呼び出しはタイムアウトのチェックを行わないことを意味し、独自のロジックを実行しているだけのスクリプトの大きなブロックもチェックされず、次の出力ステートメントが非難されることになります。

コードが遅れている場所を追跡する必要があり、タイムアウトメッセージが間違った場所を指している場合は、長時間実行されているコードの実行中に、ロギングまたはjstackを使用してサーバーからスタックトレースを取得します。数秒間隔でいくつかのスタックトレースを取得し、 Samuraiを介してログファイルを実行して、コードが何を実行しているかを確認します。

于 2012-05-09T13:21:23.880 に答える
3

あなたが説明したのは、ColdFusionでのリクエストタイムアウトチェックの制約を知っている場合、残念ながら予想される動作です。(確かに、それは期待される動作ではありません。)

タイムアウトの問題をカバーするCharlieArehartによる長いブログ投稿があります。1つのセクションには、「CFは次の操作の開始時に時刻をチェックしますが、残念ながら一部のタグについてのみ」というタイトルが付けられています。残念ながらcfscript、それらの1つではなく、タイムアウトは純粋なスクリプトコードではチェックされません。ただし、タイムアウトチェックをトリガーするタグの1つはでcfoutputあり、その知識があれば、スクリプトベースのコードで要求のタイムアウトを尊重することができます。ただし、タイムアウトをチェックする場所を自分で決定する必要があるという点で、これは手動のプロセスです。

<cffunction name="cf_checkRequestTimeout" access="public" output="false" returntype="void" hint="Force CF to check if the request has timed out.">

    <!--- CF checks Request timeout on cfoutput tag use.  --->
    <cfoutput></cfoutput>

</cffunction>

<cfscript>
    for(foo=1;foo<=61;foo++){
        sleep(1000);
        cf_checkRequestTimeout();
    }
</cfscript>

生成されたエラーは4行目を非難しますが、これは誤解を招く可能性がありますが、スタックトレースは関数が11行目から呼び出されたことを示し、コードのどのビットがタイムアウトしたかを知ることができます。明らかに、その知識の粒度は、タイムアウトをチェックする頻度に基づいています。

cf_checkRequestTimeout(これはcheckRequestTimeout文書化されていない内部CF関数であるためではありません)cfscriptの外部でも呼び出すことができるため、たとえば、cfqueryタイムアウトの問題を引き起こしていると思われる場合は、のcf_checkRequestTimeout後に呼び出しを行いcfquery、タイムアウトエラーが発生する可能性があります。コード実行のさらに下の代わりに。

于 2012-07-25T09:31:23.277 に答える
2

私はヘンリーと同じものを見つけています。これが私のテストコードです:

Before thread<br />
<cfthread action="run" name="t1">
    <cfloop condition="true">
        <cfparam name="count" default="0">
        <cfset sleep(3000)>
        <cflog file="cfthreadTest" text="Log entry #++count#">
    </cfloop>
</cfthread>
After thread<br />

CFAdminでリクエストのタイムアウトが20秒に設定されており、このスレッドは15分間実行されています。とは言うものの、スレッドは「リクエスト」ではないので、リクエストのタイムアウトを尊重することを期待できるかどうかはわかりません。リクエストのタイムアウトを尊重する必要があることを示唆する文書はありません。そうは言っても...スレッドを強制終了する方法があると「便利」です。

これは、リクエストのタイムアウトを尊重することを期待しているという点で、あなたの期待が正しいとは思わないという文脈での「答え」にすぎないと思います。

于 2012-05-09T08:44:41.073 に答える