Windows/IIS サーバーで ColdFusion 8 を使用して、何百もの PDF をバッチで生成する Web アプリケーションがあります。
プロセスは私の開発サーバーとステージング サーバーで正常に実行されますが、もちろんクライアントは安価で、私の開発/ステージング ボックスほど高速ではない共有ホスティングに対してのみ料金を支払っています。その結果、PDF 生成スレッドがタイムアウトします。
流れは次のようなものです。
- PDF を生成するためにページが実行されます。
- どの PDF を生成する必要があるかを判断するためにクエリが実行され、生成する必要がある各 PDF に対してアプリケーション スコープの UDF 呼び出しがループによって開始されます。
- その UDF は、指定されたアイテムの情報を検索し、PDF 生成用のスレッドを作成して、生成によってページの速度が低下するのを防ぎます。
- スレッドは、単に CFDocument を使用して PDF を作成し、ディスクに保存してから終了します。
スレッドは再結合せず、スレッドの終了を待っているものは何もありません。UDF 呼び出しを行うページは数ミリ秒で終了します。タイムアウトしているのはスレッド自体です。
UDF (およびスレッド作成) のコードは次のとおりです。
<cffunction name="genTearSheet" output="false" returntype="void">
<cfargument name="partId" type="numeric" required="true"/>
<!--- saveLocation can be a relative or absolute path --->
<cfargument name="saveLocation" type="string" required="true"/>
<cfargument name="overwrite" type="boolean" required="false" default="true" />
<cfset var local = structNew() />
<!--- fix save location if we need to --->
<cfif left(arguments.saveLocation, 1) eq "/">
<cfset arguments.saveLocation = expandPath(arguments.saveLocation) />
</cfif>
<!--- get part info --->
<cfif structKeyExists(application, "partGateway")>
<cfset local.part = application.partGateway
.getByAttributesQuery(partId: arguments.partId)/>
<cfelse>
<cfset local.part = createObject("component","com.admin.partGateway")
.init(application.dsn).getByAttributesQuery(partId: arguments.partId)/>
</cfif>
<!--- define file name to be saved --->
<cfif right(arguments.saveLocation, 4) neq ".pdf">
<cfif right(arguments.saveLocation, 1) neq "/">
<cfset arguments.saveLocation = arguments.saveLocation & "/" />
</cfif>
<cfset arguments.saveLocation = arguments.saveLocation &
"ts_#application.udf.sanitizePartNum(local.part.PartNum)#.pdf"/>
</cfif>
<!--- generate the new PDF in a thread so that page processing can continue --->
<cfthread name="thread-genTearSheet-partid-#arguments.partId#" action="run"
filename="#arguments.saveLocation#" part="#local.part#"
overwrite="#arguments.overwrite#">
<cfsetting requestTimeOut=240 />
<cftry>
<cfoutput>
<cfdocument format="PDF" marginbottom="0.75"
filename="#attributes.fileName#" overwrite="#attributes.overwrite#">
<cfdocumentitem type="footer">
<center>
<font face="Tahoma" color="black" size="7pt">
pdf footer text here
</font>
</center>
</cfdocumentitem>
pdf body here
</cfdocument>
</cfoutput>
<cfcatch>
<cfset application.udf.errorEmail(application.errorEmail,
"Error in threaded PDF save", cfcatch)/>
</cfcatch>
</cftry>
</cfthread>
</cffunction>
ご覧のとおり<cfsetting requestTimeout=240 />
、スレッドの先頭に a を追加して、スレッドを長持ちさせようとしました...サイコロはありません。また、CFThread タグに timeout パラメータがあることを知って少し興奮しましたが、それがスレッドに参加するとき (action=join) にのみ適用されることに気付きました。
これは共有ホストであるため、ColdFusion Administrator でデフォルトのタイムアウトを変更することはできません。
これらのスレッドをより長く存続させる方法について誰かがアイデアを持っている場合は、本当に感謝しています.