跳转到内容

XQuery/XQuery 批量作业

来自 Wikibooks,开放书籍,开放世界

您想定期运行 XQuery 作业。

我们将使用 eXist 作业调度程序。eXist 作业调度程序是围绕 Quartz 系统构建的,eXist 为此系统提供了一个 XQuery API 来添加和删除作业。

方法 1:修改 conf.xml 文件

[编辑 | 编辑源代码]

如果您有一个需要定期运行的作业,您只需在 $EXIST_HOME/conf.xml 文件中添加一行。例如,如果您有一个简单的 XQuery 脚本将 dateTime 时间戳写入日志文件,您可以添加以下行

conf.xml 的示例添加

[编辑 | 编辑源代码]

这行表示当每分钟、每小时、每月的每一天、每月的每一天和每周的每一天的秒数为 0 时,运行此作业。

 <!-- run hello world to a log file every minute 
      Fields are: Sec, Min, Hrs, Day-of-Month, Month, Day-of-Week
-->
<job xquery="/db/test/sched/datetime-logger.xq"  cron-trigger="0 * * * * ?"/>

datetime-logger.xq 示例

[编辑 | 编辑源代码]
xquery version "1.0";

(: append the current date and time to the log file :)

let $datetime := current-dateTime()
let $message := concat('Current date-time :  ', $datetime)
let $log := util:log-system-out($message)

return
<results>
   <log>{$message}</log>
</results>

日志文件中的示例输出

[编辑 | 编辑源代码]
  (Line: 7) Current date-time:  2011-07-18T15:58:00-05:00
  (Line: 7) Current date-time:  2011-07-18T15:59:00-05:00

每周 Lucene 优化的示例

[编辑 | 编辑源代码]

将以下行添加到您的 $EXIST_HOME/conf.xml 文件中。

<!-- optimize the Lucene Indexes at 10:15AM Monday -->
<job xquery="/db/system/jobs/optimize-lucene-indexes.xq"  cron-trigger="0 15 10 * * MON"/>

优化 Lucene 索引的示例 XQuery

[编辑 | 编辑源代码]

/db/system/jobs/optimize-lucene-indexes.xq 的内容

xquery version "1.0";

(: run the Lucene Optimize function after new content has been loaded :)

let $login := xmldb:login('/db', 'admin', 'YOUR-ADMIN-PASSWORD')
let $log-start := util:log-system-out(concat('Starting Lucene Optimize at :', current-dateTime()))
let $start-time := util:system-time()
let $optomize := ft:optimize()
let $end-time := util:system-time()
let $runtimems := (($end-time - $start-time) div xs:dayTimeDuration('PT1S'))  * 1000  
let $log-end := util:log-system-out(concat('Finished Lucene Optimize at :', current-dateTime()))

return
<results>
   <message>Finished ft:optimize() in {$runtimems} ms</message>
</results>

方法 2:使用 XQuery API

[编辑 | 编辑源代码]

在这种方法中,我们将使用 XQuery API 从作业调度程序中添加、查看和删除作业。

要启用 XQuery 调度程序,您可能需要在 $EXIST_HOME/extensions 中设置一行

  include.module.scheduler = true

然后键入“build”重新编译代码。

还要确保 $EXIST_HOME/conf.xml 中的行未被注释掉。

 <module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule" />

以下是添加和删除作业的两个函数。

  scheduler:schedule-xquery-cron-job($xquery-path, $cron-string, $job-id)
  scheduler:delete-scheduled-job($job-id)

注意:您必须确保您的系统中启用了 XQuery 作业调度程序模块。您可以通过以下 XQuery 验证这一点

cron 字符串的格式在 [1] 中有记录

列出已安排的作业

[编辑 | 编辑源代码]

您可以使用 scheduler:get-scheduled-jobs() XQuery 函数获取所有已安排作业的列表。这将返回一个具有以下格式的文档

<scheduler:jobs count="5" xmlns:scheduler="http://exist-db.org/xquery/scheduler">
    <scheduler:group name="eXist.System">
        <scheduler:job name="Sync">
            <scheduler:trigger name="Sync Trigger">
                <expression>2500</expression>
                <state>1</state>
                <start>2012-09-14T15:48:24.724Z</start>
                <end/>
                <previous>2012-09-25T17:31:12.224Z</previous>
                <next>2012-09-25T17:31:13.57Z</next>
                <final/>
            </scheduler:trigger>
        </scheduler:job>
    </scheduler:group>
    <scheduler:group name="eXist.User">
        <scheduler:job name="REST_TimeoutCheck">
            <scheduler:trigger name="REST_TimeoutCheck Trigger">
                <expression>2000</expression>
                <state>1</state>
                <start>2012-09-14T15:48:25.337Z</start>
                <end/>
                <previous>2012-09-25T17:31:13.337Z</previous>
                <next>2012-09-25T17:31:13.57Z</next>
                <final/>
            </scheduler:trigger>
        </scheduler:job>
    </scheduler:group>

使用 XQuery 添加和删除作业

[编辑 | 编辑源代码]

以下是添加和删除作业的系统调用的示例

xquery version "1.0";

(: unit test to add a datetime logger job to the job scheduler 
   to monitor this you can do $tail -f $EXIST_HOME/webapp/WEB-INF/logs/exist.log :)

let $xquery-path := '/db/dma/apps/job-scheduler/scripts/log-datetime.xq'

(: run the logger every minute :)
let $cron := '0 * * * * ?'

(: https://wikibooks.cn/wiki/XQuery/XQuery_Batch_Jobs :)
let $add := scheduler:schedule-xquery-cron-job($xquery-path, $cron, 'Test of Schedule XQuery Cron Job')

return
<results>
   <xquery-path>{$xquery-path}</xquery-path>
   <cron>{$cron}</cron>
   <result>{$add}</result>
</results>

避免并发作业

[编辑 | 编辑源代码]

有时您希望频繁运行轮询远程站点的作业,例如每五分钟一次。如果它找到一个文件,它可能希望传输文件。但有时传输文件的时间长于轮询频率。这将重新启动作业。

为了解决这个问题,您有两个选择。一个是能够配置 eXist 以不运行并发作业。这在 2.1 中不可用。在这种情况下,您可能需要设置一个标志来测试之前的作业是否已完成。您可以使用缓存模块为每个作业设置一个标志。

以下显示了如何使用 put/get 和 remove 函数来管理跨查询的全局状态

let $job-id := request:get-parameter('job-id', 'poll-customer-123')
let $delete := xs:boolean(request:get-parameter('delete', 'false'))

return
 if ($delete)
    then
      let $remove := cache:remove('running-jobs', $job-id)
      return <result><message>Job {$job-id} has finsihed.</message></result>
    else

  if (cache:get('running-jobs', $job-id) = 'true')
    then <result><message>Job {$job-id} is already running.</message></result> (: if the job is running then exit :)
    else
    
(: continue :)
let $set-running-flag := cache:put('running-jobs', $job-id, 'true')

return
<result>
  <message>Job {$job-id} has been started</message>
</result>
华夏公益教科书