首页 > 解决方案 > 创建并运行一次“计划任务”

问题描述

我有一些长时间运行(> 1 分钟)的任务,这些任务过去可以通过 REST 中的 xQuery 正常运行。但是,我们现在将这些服务器放置在 Amazon 负载均衡器之后,并且由于 Amazon 负载均衡器的工作方式,单个查询的持续时间不能超过 29 秒。亚马逊只会让查询超时。

注意:对此无法控制

因此,我们想出的解决方案是让 xQuery 只触发一个运行正常的计划任务。我原以为这会起作用,但有一个例外——使用类似这样的东西:

declare function jobs:create-job ($xquery-resource as xs:string, $period as xs:integer, $job-name as xs:string, $job-parameters as element()?, $delay as xs:integer, $repeat as xs:integer) as xs:boolean {
let $jobstatus := scheduler:schedule-xquery-periodic-job($xquery-resource, $period, $job-name, $job-parameters, $delay, $repeat) 
return $jobstatus

并将 $repeat 设置为 0,它运行一次,但名为“$job-title”的作业仍在计划作业列表中,为“COMPLETE”。尝试再次运行代码会出错。错误显然是无法创建另一个具有相同名称的作业。如果我更改作业名称,它将运行,所以我知道它是导致错误的名称。计划日志显示:

    <scheduler:job name="Create Vault">
        <scheduler:trigger name="Create Vault Trigger">
            <expression>30000</expression>
            <state>COMPLETE</state>
            <start>2019-08-22T20:07:14.775Z</start>
            <end/>
            <previous>2019-08-22T20:07:14.775Z</previous>
            <next/>
            <final/>
        </scheduler:trigger>
    </scheduler:job>

现在,有没有一种不同的方法可以让我们执行一次只触发一次的 xQuery,这样我们就不会遇到这个作业名称问题?还是一种告诉计划任务自毁并自行移除的方法?否则,我们将需要编写一些复杂的代码来创建另一个任务以在运行后删除作业(或者创建任务代码应该删除任何 $job-name 作业)或将它们留在后面并在名称上使用一些 GUID。

更新一

我们找到的最干净的方法是这样的(基本上如果我们去创建它时工​​作存在,删除它然后创建另一个):

declare function jobs:create-job ($xquery-resource as xs:string, $period as xs:integer, $job-name as xs:string, $job-parameters as element()?, $delay as xs:integer, $repeat as xs:integer) as xs:boolean {
let $cleanjob:= if(count(scheduler:get-scheduled-jobs()//scheduler:job[@name=$job-name]) > 0) then scheduler:delete-scheduled-job($job-name) else true() 
let $jobstatus := if($cleanjob) then scheduler:schedule-xquery-periodic-job($xquery-resource, $period, $job-name, $job-parameters, $delay, $repeat) else false()
return $jobstatus
};

我想说我们还应该检查状态并且如果它正在运行则不要删除......但是这些任务是为按需运行而构建的,但按需最多可能每天一次。最长的任务是将大约 3000 个文档格式化为 PDFS,这可能需要 20 分钟。不太可能有人会与另一个正在运行的任务发生冲突,但我们可以添加这一点来确定。

或者答案应该是检查 util:eval-async() 但这令人困惑,因为它并没有真正说它只是“壳”了执行。如果它将其线程化并等待线程,那么这也将不起作用。

标签: xqueryexist-db

解决方案


推荐阅读