Release all document locks at a specified time in Marklogic

119 Views Asked by At

We are planning to implement a locking mechanism for our documents using xdmp:lock-acquire API in MarkLogic with no timeout option. The document would be locked until the user edits and save the document. As part of this, we are in need to release all the locks at a specified time, say 12.00 AM everyday.

For this, we could use xdmp:lock-release API, but if there are many documents it would take some time to get complete.

Can someone suggest a better way to achieve this in MarkLogic?

1

There are 1 best solutions below

4
On BEST ANSWER

If you have a potentially large set of locks that you need to process, and are concerned about timeouts or other issues from doing all of the work in a single transaction, then you can break up the work into smaller chunks or individual transactions.

There are a variety of batch processing tools and frameworks to do that. CoRB is one option that makes it easy to plug in custom selectors and processing scripts, and to execute against giant sets.

If you are looking to initiate the work from a MarkLogic scheduled task and perform all of the work within MarkLogic, then you could spawn multiple tasks to process subsets.

A simple example demonstrating how to set a "chunk size" for each transaction and to keep spawning more work:

declare function local:release-locks($locks, $chunk-size){
    if (exists($locks))
    then (
      (: release all of these locks(you might apply some sort of filter to restrict to a subset, 
         and maybe a try/catch in case the lock gets released before this runs) :)
      $locks[1 to $chunk-size] ! xdmp:node-uri(.) ! xdmp:lock-release(.),

      (: now spawn the next set to be released in a separate transaction :)
      xdmp:spawn-function(function(){ 
          local:release-locks(subsequence($locks, $chunk-size+1), $chunk-size) 
        }, 
        <options xmlns="xdmp:eval">
          <update>true</update>
          <commit>auto</commit>
        </options>)
    )
    else () (: nothing left to do, stop spawning work :)
};

let $locks := xdmp:document-locks()
let $chunk-size := 1000
local:release-locks($locks, $chunk-size)

If you are looking to go down this route, there are some libraries available:

The risk of spawning multiple items onto the task server is that if there is a restart or interruption, some tasks may not execute and all locks may not be released. But if you are just looking to release all of the locks, you could then just re-run the script to kick off another round.