Re: External communication with SCXML

Le 14 feb 2013 à 02:49, Stefan Radomski a écrit :

> 			<transition event="data.wien" target="final">

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.


> This solution is pretty much the one described by David, though I do not support all request types yet.

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>).


> Serving data is somewhat more convoluted then fetching. I offer "httpserver" invokers, which take again a callback as the name of the events they will generate and a path as part of an url, where the interpreter is waiting for basichttp events anyway. As soon as I have a request at the invokers url, I populate _event with _event.reqId, _event.content, _event.headers and _event.type, set the callback as its name and deliver it to the interpreters external queue.
> To reply to such a request, I expect an event called "'reply.' + _event.reqId" send to the invoker's id. Params or namelist will end up as header fields and the content as the response content obviously. To give an idea about the performance: the above request/reply cycle takes a little more than 10ms to complete (measured with "time wget …") on localhost.
> 
> I do like to have explicit "httpserver" invokers (though I might rename them to "httpservlet" still) to have control over the path where the interpreter will accept requests, but the way the replies are constructed takes some getting used to. 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.
> 
> Does anyone have some suggestions on how to integrate more closely with SCXML's language features?

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 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.

			David

Received on Thursday, 14 February 2013 07:59:02 UTC