У меня есть веб-приложение, которое генерирует сотни PDF-файлов в пакетном режиме, используя ColdFusion 8 на сервере Windows/IIS.Увеличьте время ожидания запроса для потока в CFML
Процесс отлично работает на моих серверах разработки и промежуточного уровня, но, конечно, клиент дешев и платит только за общий хостинг, который не так быстро, как у моих dev/промежуточных ящиков. В результате потоки генерации PDF синхронизируются.
Поток что-то вроде этого:
- Страница выполняется для создания PDF-файлов.
- Выполняется запрос для определения того, какие PDF-файлы должны быть сгенерированы, а цикл запускает вызов UDF с областью приложения для каждого PDF-документа, который необходимо будет сгенерировать.
- Этот UDF просматривает информацию для данного элемента, а затем создает поток для генерации PDF, в котором работает, что предотвращает замедление производства.
- В потоке просто используется документ CFDocument для создания PDF-файла и сохранения его на диск, а затем завершается.
Нити не присоединяются, и ничто из них не ждет завершения. Страница, на которой заканчиваются вызовы 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 />
к верхней нити, чтобы попытаться сделать это жить дольше. .. нет кости. Я также немного взволновался, когда увидел, что the CFThread tag has a timeout parameter, но затем понял, что он применяется только при соединении потоков (action = join).
Изменение тайм-аута по умолчанию в ColdFusion Administrator не является вариантом, так как это общий хост.
Если у кого-то есть идеи о том, как сделать эти потоки живыми дольше, я бы очень их оценил.
Как вы знаете, что потоки выходят из строя? Я не особенно знаком с Enterprise, но на моих стандартных ящиках заброшенные потоки не кажутся тайм-аутами. –
Я получаю письма с ошибкой через метод onError() приложения.cfc, вызываемый при тайм-ауте потоков. Кроме того, хостинг-провайдер сообщает мне, что те же сообщения отображаются в журнале ошибок. –