跳轉到內容

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://wikibook.tw/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>
華夏公益教科書