Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server-Side JavaScript support #2

Open
jmakeig opened this issue Dec 1, 2014 · 3 comments
Open

Server-Side JavaScript support #2

jmakeig opened this issue Dec 1, 2014 · 3 comments

Comments

@jmakeig
Copy link

jmakeig commented Dec 1, 2014

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.

@mblakele
Copy link
Owner

mblakele commented Dec 8, 2014

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.

@jmakeig
Copy link
Author

jmakeig commented Dec 10, 2014

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.

@mblakele
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants