taskbot icon indicating copy to clipboard operation
taskbot copied to clipboard

Server-Side JavaScript support

Open jmakeig opened this issue 11 years ago • 3 comments

With MarkLogic 8, it would great to be able to specify tasks as JavaScript in addition to XQuery. I don't know how much surgery this would be; I haven't tested it. Worst case is a parallel rewrite, though I think the orchestration could remain in XQuery and the user-specified task and filter logic could be pluggable with JavaScript. I’ll take a first crack at characterizing the changes and propose something in a pull request.

jmakeig avatar Dec 01 '14 23:12 jmakeig

To make this happen I think we need to solve two problems. They seem to be closely related, so solving either will probably solve both.

First, we need xdmp:invoke-function and xdmp:spawn-function to accept JavaScript functions instead of throwing XDMP-AS: (err:XPTY0004) xdmp:invoke-function($fn) -- Invalid coercion: function () as function() as item()*.

Related to that, we need function type specifiers to work with JavaScript while remaining backward-compatible with ML7. In various places taskbot's functions expect $fn as function() as item()* and $fn as function(item()+, map:map?) as item()* and $fn as function() as xs:boolean. Today those all reject JavaScript functions. Here's a simple test case to give you the idea:

declare function local:test($fn as function() as item()*)
{
  $fn()
};

local:test(function() { current-dateTime() }),
local:test(xdmp:javascript-eval('var f = function() { return new Date(); }; f;'))
XDMP-AS: (err:XPTY0004) $fn as function() as item()* -- Invalid coercion: function () as function() as item()*

The difference appears to be cosmetic: if I change the signature to $fn as item() or drop the typing entirely, then both tests work. I recognize that I might have to weaken some of those function types to account for the nature of JavaScript. But despite that I want to retain as much strong typing as possible inside the taskbot code. Anyway the fixes for xdmp:invoke-function and xdmp:spawn-function should solve at least part of this.

mblakele avatar Dec 08 '14 00:12 mblakele

Unfortunately a JavaScript equivalent of xdmp:spawn-function will not be available in 8.0-1. It’s something we definitely want to do, but there are some issues with V8 isolation boundaries that make this infeasible in the short term. That sounds like a blocker here.

jmakeig avatar Dec 10 '14 19:12 jmakeig

Yes, that looks like a show-stopper. Calling xdmp:spawn-function throws the same XDMP-AS above. I thought it might be possible to encapsulate the JavaScript function in an anonymous XQuery function, but that also fails.

let $fn := xdmp:javascript-eval(
  'var f = function() { xdmp.log("hello from javascript!"); }; f;')
return xdmp:spawn-function(
  function() {
    xdmp:log('test start'),
    $fn() })

That logs an error:

2014-12-10 12:57:57.635 Info: TaskServer: test start
2014-12-10 12:57:57.636 Notice: TaskServer: JS-APPLY: function() as item()*() -- Cannot apply function: 
2014-12-10 12:57:57.636 Notice: TaskServer: in / [1.0-ml]

A similar test with xdmp:invoke-function works, so this looks like a V8 problem.

mblakele avatar Dec 10 '14 21:12 mblakele