У меня есть веб-приложение, которое генерирует сотни PDF-файлов в пакетном режиме, используя ColdFusion 8 на сервере Windows / IIS.
Процесс отлично работает на моих серверах разработки и промежуточных серверах, но, конечно, клиент дешевый и платит только за виртуальный хостинг, который не так быстр, как мои устройства разработки / размещения. В результате потоки создания PDF-файлов истекают.
Поток примерно такой:
- Страница запускается для создания PDF-файлов.
- Запускается запрос, чтобы определить, какие PDF-файлы необходимо сгенерировать, и цикл запускает вызов UDF прикладной области для каждого PDF-файла, который необходимо сгенерировать.
- Этот 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 />
в начало потока, чтобы попытаться заставить его жить дольше ... без кубиков. Я также был немного взволнован, когда увидел, что тег CFThread имеет параметр времени ожидания , но потом понял, что он применяется только при присоединении к потокам (action = join).
Изменение времени ожидания по умолчанию в ColdFusion Administrator не является вариантом, поскольку это общий хост.
Если у кого-нибудь есть идеи о том, как заставить эти темы жить дольше, я буду очень признателен за них.