Re: External communication with SCXML

Hey David,

thank you for your comments.

On Feb 14, 2013, at 8:58 AM, David Junger <tffy@free.fr>
 wrote:

> My implementation currently would send "data.wien.done" instead. But it seems other people find it more intuitive to send the exact callback. Something should be done then to deal with failed requests.

"data.wien" will match "data.wien.done" as well, so there is no problem with someones intuition if we send "data.wien.done". You will send an "error.communication" on a failed fetch?

> I think it's completely reasonable that types should be platform-specific. plain text should be mandatory ; JSON too for datamodel="ecmascript" ; urlencoding is useful with old-fashionned form-based services and easy to implement so should probably be mandatory too ; XML should be mandatory for the XML datamodel only, it can be useful otherwise but you need a DOM representation in the other datamodels for it to make any sense (otherwise just send XML as text and add the correct Content-Type <header>).

We already have a complete SCXML DOM with a Core Level 2 API exposed to the ecmascript datamodel, so it's not too complicated for us to support  arbritary XML as DOM nodes as well. I do think that we should harmonize as much as possible to eventually propose the approach for inclusion in the draft - if it is considerd "in-scope".

> I had thought of something like this to filter request URLs:
> 
> <transition event="http.request" cond="_event.data.path=='/data'>
> 	…
> </transition>
> 
> The _event.data would contain the properties 'URL', 'headers', 'clientIP', 'body', 'method', 'path', 'query'
> ('path' and 'query' are just convenience properties to access parts of the request URL)
> _event.origin would contain the internal 'requestID'
> 
> You would then probably <invoke> a separate interpreter to process each request (mostly to avoid mixing data and state from different requests).

I'd definitely leave this for an application developer to decide. You might actually want to change some global state.

> I still think you shouldn't use <send> to respond. I would do it like this (assuming I have stored the request's _event in 'req'), using the same attributes and elements as in <fetch>:
> 
> <respond status="200" request="req.origin" type="json" close>
> 	<header name="Cross-Domain-Allow-Origin" expr="req.data.clientIP"/>
> 	<header name="Cross-Domain-Allow-Methods" expr="''GET POST"/>
> 	<param name="result" expr="_ioprocessors"/>
> </respond>
> 
> where the 'close' boolean attribute tells the platform to close the connection (or not) ; if not, then you could <respond> to the same request in several steps, progressively adding more content.
> 'status' would be 200 by default of course, but I wanted to show it.
> 
>> One remaining problem is that the last send is never delivered: The event from "http.exit" will trigger the transition to the final state and the invoker will already be gone. But I don't think this is something a response element could solve as it will have the same problem.
> 
> Transition content is executed before the entry step, so you would not yet be in a final state if you respond in the transition content. But the exit step would have been taken, so yes, the invocation would be terminated already. My solution solves it by putting the platform itself in charge of handling the connections. The server would terminate only when the top-level SC terminates.
> 

The more I think about it, the more I like the approach you outlined, at least with respect to the platform being in charge. Having dedicated invokers to register at urls is nice to get some control about available URL paths, but then again, having respective transitions with their conds will accomplish the same thing and solves the "vanished invoker" without some more elaborate state structure. I was concerned about passing all kinds of requests into the interpreter, but then again, the basichttp ioprocessor already does that.

In fact, we would need to distinguish incoming requests on whether they are meant to be basichttp requests with an immediate reply or "respondable requests". *Every* request at the access URI is a valid basichttp request as per [1] and expects an immediate reply. That would only leave the paths beneath the access URI available to be interpreted as respondable requests or another access URI e.g. on second http server (which I'd definitely like to avoid).

At the moment, the access URI for SCXML sessions in my implementation is http://hostname:firstFreePortAbove8080/interpreterNameWithEventualDigitsPrependedOrUUID/. As I see it, we have a couple of options:

1. Even respondable requests get passed into the interpreter as per [1] (request method or _scxmlEventName header value as the eventname) and we send a simple, "200 OK" if we reach a stable configuration without passing a respond. This would still behave as described in the draft, but we could not wait for intermediate events as we will close the request before waiting for more external events.

1.1 Introduce a <postpone request="_event.origin"> to inhibit the immediate response on the next stable configuration so we could answer later, but that seems somewhat counter-intuitive.

2. Only process requests with a _scxmlEventName header set as basichttp requests and use the respondable requests for everything else. This violates the draft for all requests directed at the access URI.

3. Process everything directed at the access URI as a basichttp and everything with an additional path component as a respondable request. This violates the puristic REST view somewhat as the response from the access URI should tell you about all the more detailed URIs.

4. Violate the draft and interpret everything as respondable requests.

Does anyone see another possibility here to distinguish basichttp and respondable requests? I am inclined to go with the second option as the current basichttp approach seems insufficient anyway and 1.1 seems like too much for an application developer to be concerned about.

Best regards
Stefan

[1] http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor

Received on Thursday, 14 February 2013 12:34:13 UTC