无法从CPF操作模块中创建MarkLogic计划任务

时间:2014-10-21 17:59:13

标签: scheduled-tasks marklogic

我有一个安装了Content Processing Framework(CPF)的MarkLogic数据库,CPF管道就是:

  1. 每当插入文档时,它都会从文档中获取 execution-date 的值,并为该时间安排任务。
  2. 示例:

    示例文件:

    <sample>
      <execution-date>2014-10-20T12:29:10</execution-date>
    </sample>
    

    插入时触发CPF操作模块,该模块读取执行日期字段的值,并创建要在执行日期字段读取的时间执行的计划任务。

    以下是来自CPF操作模块的XQuery代码段,用于创建计划任务:

    let $doc := fn:doc( $cpf:document-uri )
    let $releasedon := xs:string($doc/sample/execution-date/text())
    
    let $config := admin:get-configuration()
    let $group := admin:group-get-id($config, "Default")
    
    let $new-task :=
         admin:group-one-time-scheduled-task(
            "/tasks/task.xqy",
            "/",
            xs:dateTime($releasedon),
            xdmp:database("SampleDB"),
            xdmp:database("Modules"),
            xdmp:user("admin"), 
            (),
            "normal")
    
    let $addTask := admin:group-add-scheduled-task($config,$group, $new-task)
    
    return
    
        admin:save-configuration($addTask),
        xdmp:log(fn:concat("Task for document Uri: ", $cpf:document-uri, " created"))
    

    现在,当我插入单个文档时,一切都按预期工作,即:

    1. 文件已成功插入
    2. 成功触发CPF操作模块
    3. 计划任务已成功创建。
    4. 但是,当我尝试使用以下方法插入多个文档时

      xdmp:document-insert("/1.xml", 
          <sample>
            <execution-date>2014-10-21T10:00:00</execution-date>
          </sample>, 
          xdmp:default-permissions(),
          ("documents"))
      ,
      xdmp:document-insert("/2.xml", 
          <sample>
            <execution-date>2014-10-20T11:00:00</execution-date>
          </sample>, 
          xdmp:default-permissions(),
          ("documents"))
      

      CPF操作模块成功触发(日志消息可在日志中看到) 创建一个计划任务。

      查看MarkLogic管理界面时,我只能找到计划在 2014-10-20T11:00:00

      运行的单个计划任务

      请让我知道我做错了什么,或者我缺少任何配置。 欢迎任何建议。

      谢谢!

2 个答案:

答案 0 :(得分:3)

这里的根本问题是管理员配置操作API 不是事务保护操作,所以当你并行运行两个时,每个人都会看到配置文件的初始状态,然后将它们写入添加计划任务,然后保存,只有其中一个获胜。您可以通过强制锁定某些URI来强制它以受事务保护的方式运行。它无关紧要。它甚至不必在数据库中。只要执行此操作的所有内容都锁定在同一URI上,您就可以了。 xdmp:lock-for-update("my.example.uri")会这样做。

答案 1 :(得分:0)

以下CPF操作模块现在按预期工作:

xquery version "1.0-ml";
import module namespace cpf = "http://marklogic.com/cpf" at "/MarkLogic/cpf/cpf.xqy";
import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy";

declare variable $cpf:document-uri as xs:string external;
declare variable $cpf:transition as node() external;

declare function local:scheduleTask()
{

xdmp:lock-for-update("/sample.xml"),
if (cpf:check-transition($cpf:document-uri,$cpf:transition)) then try
{

    let $doc := fn:doc( $cpf:document-uri )
    let $releasedon := xs:string($doc/sample/execution-date/text())

    let $config := admin:get-configuration()
    let $group := admin:group-get-id($config, "Default")

    let $new-task :=
         admin:group-one-time-scheduled-task(
            "/tasks/task.xqy",
            "/",
            xs:dateTime($releasedon),
            xdmp:database("SampleDB"),
            xdmp:database("Modules"),
            xdmp:user("admin"), 
            (),
            "normal")

    let $addTask := admin:group-add-scheduled-task($config,$group, $new-task)

    return

        admin:save-configuration($addTask),
        xdmp:log(fn:concat("Task for document Uri: ", $cpf:document-uri, " created")) 

}
catch ($e) {
    cpf:failure( $cpf:document-uri, $cpf:transition, $e, () )
}
else ( )
};

local:scheduleTask()