RE: [EXTERNAL] - Hacking at injection

What about a Spring AOP-like approach? Instead of inserting new steps into the dependency graph, the processor could simply create "proxy steps" that would wrap around the inspected steps and intercept the before/during/after/... stages of the invocation? Using the AOP/AspectJ terminology, you would be defining pointcuts (expressions identifying the steps you want to inspect) and advices (actions to be taken when a point in execution with a matching pointcut is reached). You could register Before advices that will be executed before a step runs, After advices that will get executed after the step runs, etc.

It might also be useful to allow, in addition to being able to point to specific steps, to create pointcuts that match steps with a specific QName (for instance, to trace all p:http-request steps), or even a namespace (to trace all steps from a 3rd-party library).

Apart from the obvious use for tracing/debugging, you could the AOP-like approach use this for processor-dependent things like ensuring that a step (or a sequence of steps) runs in a transaction etc.

Regards,
Vojtech


-----Original Message-----
From: Norman Walsh [mailto:ndw@nwalsh.com] 
Sent: Sunday, October 01, 2017 10:42 PM
To: XProc Dev
Subject: [EXTERNAL] - Hacking at injection

Hi folks,

I’ve spent a little time this weekend hacking around the edges of the injection problem. Here’s an example of what I’ve come up with so far:

<p:injectable xmlns:p="http://www.w3.org/ns/xproc"
              xmlns:c="http://www.w3.org/ns/xproc-step">

  <p:input step="/p:declare-step/p:identity[1]" port="source"
           message="Document sent to identity[1] on source"/>

  <p:input step="//p:identity" port="source"
           base-uri="pipe.xpl"
           message="Document sent to identity on source for pipe"/>

  <p:output step="/*/p:wrap-sequence" condition="$opt-class = 'b'">
    <doc class="{$opt-class}">{.}</doc>
  </p:output>

  <!-- also p:step for when a step runs --> </p:injectable>

The idea is that you can put an “inspector” on a particular input port or on a particular output port. (The comment at the bottom aludes to a p:step injectables as well, for when a step executes; I’m less confident about that one, purely on implementation grounds.)

In order to insert something, you have to be able to point to it.
Pointing with step names doesn’t work because you need to have something that’s unique across the whole pipeline, not just in a particular scope. Rather than inventing a new kind of step addressing language, I just went with XPath.

If you don’t specify a base URI, the injector applies to all pipelines (which is fine because usually there’s only one anyway).

The message can be either an attribute or content. If it’s an attribute, it’s an AVT so you can inspect the in-scope variables at the point of insertion. It’s an error if you refer to variables that aren’t in scope at that point.

If the message is content, it’s like p:inline, it expands the TVT.

Condition let’s you specify when you’d like the injectable to “fire”.

There’s still lots of unanswered questions, like where does the output go?

I’m implementing this by literally inserting steps into the graph.
That complicates the graph, which could change behavior, but it means the injectables can refer to different variables than the steps.

                                        Be seeing you,
                                          norm

--
Norman Walsh
Lead Engineer
MarkLogic Corporation
Phone: +1 512 761 6676
www.marklogic.com

Received on Monday, 2 October 2017 07:58:02 UTC