https://github.com/mblakele/presta is now available. This library started when
I noticed the new 'result' option for xdmp:spawn in MarkLogic 5.0. That looked
handy, but xdmp:spawn still wanted me to supply a module path. I wanted to
write XQuery tasks with arbitrary code strings, like this:
for $i in 1 to 4
return xdmp:spawn-eval(
'xdmp:sleep(1000)', (),
<options xmlns="xdmp:eval">
<result>true</result>
</options>),
xdmp:elapsed-time()
...and have all four tasks execute in parallel, using all my CPUs and returning
the results. Here's what I ended up with:
import module namespace presta="com.blakeley.presta"
at "presta.xqy";
let $presta-id := presta:prepare('xdmp:sleep(1000)')
for $i in 1 to 4
return presta:spawn(
$presta-id, (),
<options xmlns="xdmp:eval">
<result>true</result>
</options>),
xdmp:elapsed-time()
The presta:spawn function works just like xdmp:spawn, and takes the same
arguments - except that the first parameter is a presta id not a module path.
We get that id by calling presta:prepare, which takes the XQuery string and
stores it the Modules database.
The id for a Presta module is based on xdmp:hash64, so preparing the same
XQuery twice will return the same id. Presta tries not to update the Modules
database any more than necessary - but it's still best to stash these ids
somewhere if you can.
Once prepared, we can also use a presta id with presta:invoke. This is handy
for apps that eval the same strings frequently, because the Presta module
works with the module cache. And we don't have to keep the XQuery around after
it has been registered. This could be a way for developers using Java to get
some of the performance benefits of invoke, without having to write every
XQuery module in advance.
But there's more to MarkLogic than XQuery. We can also call presta:prepare with
XSLT, and then call presta:xslt-invoke.
We need libraries, too. So you can call presta:import to install a library
module where other Presta functions can find it.
presta:import(
'lib-test.xqy',
'module namespace t="com.blakeley.presta.test";
declare function t:now() { fn:current-dateTime() };')
presta:invoke(
p:prepare(
'import module namespace t="com.blakeley.presta.test"
at "lib-test.xqy";
t:now()
I almost forgot about environments with multiple applications. Every app-server
automatically gets its own Presta environment, based on the appserver id from
xdmp:server(). If you want multiple servers to share the same Presta modules,
we can call presta:appkey-set('my-app-key'). If you want to keep modules
somewhere other than the Modules database, set the app-server modules location
to any database you like.
Of course I also wanted Presta to work with profiling. Presta supports cprof,
and includes a copy of the cprof library. My plan is to discontinue cprof as a
separate project, and include it as part of Presta.
Finally, Presta works with the security model. Presta installs a new role that
you can grant to any user.
The code is at https://github.com/mblakele/presta - I hope it's useful.
-- Mike
_______________________________________________
General mailing list
[email protected]
http://community.marklogic.com/mailman/listinfo/general