Re: An IDL for SCXML interpreters

Jacob Beard <[email protected]> Tue, 14 Jul 2015 09:38:13 -0400
Newsgroups gmane.comp.web.voice
Message-ID <[email protected]>
--Apple-Mail=_21B62C63-F893-4F3D-B1C3-F2DAFA8685F6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

Hi Stefan,

Please excuse the delay in my reply.

> On Jul 3, 2015, at 10:01 AM, Stefan Radomski =
<[email protected]> wrote:
>=20
> Hey there,
>=20
> [explicitly bcc'ing David, Jacob and Zjnue for I know that they =
maintain SCXML implementations] - this post is pertaining to action =
point 1 from my previous mail:
>=20
> 1. An Interface Description Language (IDL) for SCXML interpreters.
> 1.1 For simple life-cycle and interpretation of state-charts.
> 1.2 A set of hooks for (on-line) visualisation.
> 1.3 A set of hooks for (on-line) modelling / debugging.
>=20
> For now, I'd like to focus on point 1.1, but we ought to keep the =
others in mind and maybe eventually extend our ambitions. At least 1.2 =
is very useful as it would allow or a common visualisation. I hereby =
propose a first sketch for an Interface Description Language (IDL) for =
SCXML (see below). It will only allow to instantiate interpreters, run =
them and deliver events. A typical session would look like this:
>=20
> import namespace scxml;
> try {
> Interpreter session =3D Implementation.fromURI("http://www =
<http://www/>.example.com/foo.scxml");
> for(;;) {
> int state =3D session.step();
> if (state =3D=3D FINISHED)
> break;
> if (state =3D=3D AFTER_MACROSTEP && session.configuration.in('foo'))
> session.receive('bar.baz');
> }
> } catch (Exception e) {
> print e;
> }
>=20

Here are my comments on this.

In SCION, there=E2=80=99s a notion of compiling the SCXML into a =
=E2=80=9Cmodel=E2=80=9D object, which is a native object used to create =
the session (scxml.urlToModel =
<https://github.com/jbeard4/SCION#scxmlurltomodelurlfunctionerr-model>). =
This gives the client a way to create multiple sessions without =
reparsing/recompiling the SCXML into its object representation, which is =
a relatively expensive operation.=20

Additionally, the model can be can be parsed from a DOM object =
(scxml.documentToModel =
<https://github.com/jbeard4/SCION#scxmldocumenttomodelscxmldocumentfunctio=
nerr-model>), which provides opportunities for model transformation =
using XML DOM API. Finally, in SCION there are convenience methods for =
parsing SCXML from filesystem (scxml.pathToModel =
<https://github.com/jbeard4/SCION#scxmlpathtomodelpathfunctionerr-model>),=
 and from a string representation (scxml.documentStringToModel =
<https://github.com/jbeard4/SCION#scxmldocumentstringtomodelscxmldocstring=
functionerr-model>).

After that, can you instantiate the session using the model object: =
scxml.scion.Statechart(model, options)

It=E2=80=99s useful to have a mechanism to specify the SCXML _sessionid. =
This is passed in on the options argument.

session.step() seems equivalent to session.start() in SCION. This causes =
the state machine to enter its initial state.

Currently in SCION, the return value of session.start() is a basic =
configuration (set of basic states), encoded as a JavaScript array =
containing state id strings. In SCION, the basic configuration is kept =
as an internal data structure, so this cheap to return.=20

In terms of querying the session for current state, you can use =
session.getConfiguration() to get the basic configuration, and use =
regular JavaScript semantics to query the array (e.g. =
"configuration.indexOf(=E2=80=99stateId') > -1=E2=80=9D). You can a can =
also use session.isIn(=E2=80=99stateId') to query the session for basic =
and composite states.

In SCION, session.gen() is equivalent to session.receive(). I chose the =
name =E2=80=9Cgen" from Harel=E2=80=99s paper The Rhapsody Semantics of =
Statecharts =
<http://research.microsoft.com/apps/pubs/default.aspx?id=3D148785>. In =
SCION, the return value is the same as session.start(): a basic =
configuration.

Finally, you can use session.isFinal() to check if the session is in a =
final state.

Altogether, here is an example of the SCION API:

    scxml.urlToModel(url,function(err, model){

        if(err) throw err;

        //you can inspect the generated code if you like using =
JavaScript's Function.prototype.toString
        console.log(model.toString());      =20

        //instantiate the interpreter
        var statechart1 =3D new scxml.scion.Statechart(model);

        //you can instantiate a second interpreter using the same model
        var statechart2 =3D new scxml.scion.Statechart(model);

        //start the interpreter
        var initialConfiguration =3D statechart1.start();

        //send events
        statechart1.gen({name : 'foo', data : 'bar'});
    });


> A couple of notes and possible variations:
>=20
> =3D=3D 1. Threads
> I want to avoid any assumptions about the availability of threads in =
the embedding platform. As such, there is e.g. no non-blocking =
interpret(). It would be the responsibility of the target platform to =
emulate something like this by embedding the block above in a thread.
>=20

I agree with this. A blocking API for interpret/receive/gen works well =
with the notion of =E2=80=9CFast Computation=E2=80=9D for big-step =
modeling languages described in section 2.3 of Big-Step Semantics =
<https://cs.uwaterloo.ca/~sesmaeil/publications/2009/CS-2009-05.pdf> by =
Nancy Day, et al. gen() should be a fast, synchronous, blocking =
operation.

> =3D=3D 2. Exceptions
> Similarly I want to avoid any assumption about the availability of =
exceptions, therefore step() might return FAULT and set the lastError =
attribute:
>=20
> int state;
> for(;;) {
> state - session.step();
> switch(state) {
> case FAULT:
> print session.lastError;
> break;
> case FINISHED:
> return;
> }
> }
>=20

I=E2=80=99ve been considering this. The SCXML spec says that scripting =
errors should be put on the internal queue as error.execution events. =
However, from a developer perspective, I often find this behavior =
surprising. The developer needs to remember to add a top-level =
<transition event=3D=E2=80=9Cerror.*=E2=80=9D> to catch execution errors =
exposed as events. So by default, in SCXML, JavaScript errors are =
suppressed. I therefore think it could be useful if the interpreter API =
could provide better visibility so that execution errors are by default =
not suppressed.=20


> =3D=3D 3. Data
> 0. If nothing in a Data object is set, its value is undefined
> 1. If an atom is given, the respective field is to be interpreted as =
the evaluation of that atom, e.g. "3" is a string, 3 is an integer.
> 2. If a node is given and 1. is not the case, the field is to be =
represented as a DOM Node
> 3. If a key in a compound is set and 1. and 2. are not the case, the =
respective field is a map
> 4. If an index is set and none of the above applies, the respective =
field is an array. Setting a an item at an index N will cause the array =
to behave as if it has N fields for the largest N. With all unset fields =
undefined.
>=20

In SCION, the datamodel is kept fully private, and not exposed =
externally, except via the session.getSnapshot() method, which returns a =
copy of the full datamodel. This is a relatively cheap operation.

> =3D=3D 4. Event
> Having most fields visible will allow for interpreters where all i/o =
processors are external by simply delivering respective Event entities =
via receive. The distinction between internal and external events ought =
to happen in receive(Event) itself depending on the event's type field. =
I am not sure if we need the PLATFORM class though.

I agree that receive() should be able to accommodate both internal and =
external events. It should be possible to inspect the _event.origin =
field and compare it to _ioprocessors to determine whether an event =
originating internal or external to the session.

>=20
> =3D=3D 5. Hibernating
> We might want to include a way to serialise a complete interpreter and =
instantiate it again from its serialised representation. I do know that =
Jacob was working on a respective feature. We dropped our ambitions for =
now as most of the datamodels we employed via 3rd party libraries would =
not support something like that.
>=20

Right now, in SCION, datamodel elements that are =E2=80=9Ctransient=E2=80=9D=
 (not serializable) are initialized in the top-level <script> tag, which =
is executed every time a session is instantiated. Rather than put them =
in the datamodel, they are declared in the <script> tag using JavaScript =
=E2=80=9Cvar=E2=80=9D. I think this is a bit ugly, and could be =
improved. To improve this, two things would be needed:

1. An explicit notion of transient attributes on the datamodel. This is =
similar to the =E2=80=9Ctransient" attribute modifier in Java. These =
datamodel elements would not be serialized on hibernate.
2. Explicitly recognizing that top-level script tag is a code block that =
will executed on resume. This allows transient datamodel elements to be =
re-initialized.=20

State machine hibernation is useful for developing scalable cloud =
applications, as it allows your SCXML session data to be persisted to =
secondary storage, rather than kept in memory. This is needed for =
horizontal scalability.

> =3D=3D 6. Naming
> AFTER_MACROSTEP might just as well be called STABLE. I choose the =
former for its more explicit reference to the runtime semantics of =
SCXML, which might play a role if we were to specify a bunch of hooks =
for 1.2 and 1.3 (see debugger paper[1], table 1)
>=20

I think it would be useful to explicitly capture these interpreter =
states as a meta-state machine.

It may be interesting to look at the states in the docker container =
lifecycle, as docker provides a generic container API for linux =
applications. These concepts could carry over to modeling the SCXML =
interpreter lifecycle. I created an SCXML to model this here: =
http://examples.scxml.io/e/docker-manager/ =
<http://examples.scxml.io/e/docker-manager/>
> =3D=3D 7. Events *from* the interpreter
> While point 4 allows an embedding platform to send arbitrary events =
*into* the interpreter, maybe we ought to have something similar for =
everything <send> from the interpreter?
>=20

I think we should consider an API for <send>. I=E2=80=99m currently =
working on improving the SCION <send> implementation, including support =
for custom send types, and will follow up on this item shortly.

>=20
> Maybe anyone who is interested in pursuing the idea of this basic IDL =
could speak up and comment about the proposal? What is missing, what is =
superfluous for a basic IDL?

Thank you for getting this process started. Please let me know your =
feedback, and I can take a pass at iterating on the proposed IDL.

Regards,

Jacob Beard

>=20
> Regards
> Stefan
>=20
> [1] =
http://scxmlworkshop.de/eics2014/submissions/A%20Debugger%20for%20SCXML%20=
Documents.pdf
>=20
>=20
>=20
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>=20
> module scxml {
>=20
> exception Exception {
> const unsigned short PARSE_ERR =3D 1; // Given string could not be =
parsed as an xml document
> const unsigned short SCHEMA_ERR =3D 2; // XML DOM not a valid SCXML =
document
> const unsigned short IMPL_ERR =3D 4; // Unknown datamodel, ioproc, =
executable content or invoker used
>=20
> unsigned short code;
> String cause;
> };
>=20
>=20
> // central place to get interpreter instances
> interface Implementation {
> Interpreter fromURI(in String uri) raises(Exception);
> Interpreter fromXML(in String xmlString) raises(Exception);
> Interpreter fromDOM(in Node scxmlRoot) raises(Exception);
> }
>=20
> interface Event {
> const unsigned short PLATFORM_EVENT  =3D 1;
> const unsigned short INTERNAL_EVENT  =3D 2;
> const unsigned short EXTERNAL_EVENT  =3D 3;
>=20
> String name;
> unsigned short type;
> String origin;
> String originType;
> String sendid;
> Data data;
> };
>=20
> interface Data {
> set(in String value); // atom
> String get();
>=20
> setNode(in Node node); // XML node
> Node getNode();
>=20
> setKey(in String key, in Data value); // compound
> Data getKey(in String key);
>=20
> setItemAt(in String index, in Data value); // array
> Data getItemAt(in String index);
> };
>=20
> interface Configuration {
> boolean in(in String state);
> String item(in unsigned long index);
> readonly attribute unsigned long length;
> };
>=20
> interface Interpreter {
> const unsigned int FAULT =3D 0; // something bad happened, look into =
lastError
> const unsigned int AFTER_MICROSTEP =3D 1; // step finished with a =
single microstep
> const unsigned int AFTER_MACROSTEP =3D 2; // step finished with a =
single macrostep and interpreter is stable
> const unsigned int SCXML_IDLE =3D 3; // interpreter is stable with no =
pending events on queues
> const unsigned int SCXML_FINISHED =3D 4; // interpreter reached =
top-level final state
>=20
> const unsigned int step() raises(Exception) raises(Exception); // =
blocking per default
> const unsigned int step(in int timeOutMs) raises(Exception); // block =
at most for given duration, 0 for non-blocking
>=20
> receive(in Event event);
> receive(in String event); // convenience
>=20
> readonly attribute Exception lastError;
> readonly attribute Configuration configuration;
> readonly attribute Configuration basicConfiguration;
> }
> }
>=20
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D


--Apple-Mail=_21B62C63-F893-4F3D-B1C3-F2DAFA8685F6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><span style=3D"font-family: -apple-system-font; line-height: =
16px;" class=3D"">Hi Stefan,</span><div style=3D"font-family: =
-apple-system-font; line-height: 16px;" class=3D""><br =
class=3D""></div><div style=3D"font-family: -apple-system-font; =
line-height: 16px;" class=3D"">Please excuse the delay in my =
reply.</div><div style=3D"font-family: -apple-system-font; line-height: =
16px;" class=3D""><br class=3D""></div><div><blockquote type=3D"cite" =
class=3D""><div class=3D"">On Jul 3, 2015, at 10:01 AM, Stefan Radomski =
&lt;<a href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a>&gt; =
wrote:</div><br class=3D"Apple-interchange-newline"><div class=3D"">

<meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dus-ascii" class=3D"">

<div style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D"">
Hey there,<br class=3D"">
<br class=3D"">
[explicitly bcc'ing David, Jacob and Zjnue for I know that they maintain =
SCXML implementations] - this post is pertaining to action point 1 from =
my previous mail:<br class=3D"">
<br class=3D"">
1. An Interface Description Language (IDL) for SCXML interpreters.<br =
class=3D"">
1.1 For simple life-cycle and interpretation of state-charts.<br =
class=3D"">
1.2 A set of hooks for (on-line) visualisation.<br class=3D"">
1.3 A set of hooks for (on-line) modelling / debugging.<br class=3D"">
<br class=3D"">
For now, I'd like to focus on point 1.1, but we ought to keep the others =
in mind and maybe eventually extend our ambitions. At least 1.2 is very =
useful as it would allow or a common visualisation. I hereby propose a =
first sketch for an Interface Description
 Language&nbsp;(IDL) for SCXML (see below). It will only allow to =
instantiate interpreters, run them and deliver events. A typical session =
would look like this:<br class=3D"">
<br class=3D"">
import namespace scxml;<br class=3D"">
try {<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>Interpreter session =3D =
Implementation.fromURI("<a href=3D"http://www/" =
class=3D"">http://www</a>.<a href=3D"http://example.com/foo.scxml" =
class=3D"">example.com/foo.scxml</a>");<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>for(;;) =
{<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>int =
state =3D session.step();<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if =
(state =3D=3D FINISHED)<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br =
class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if =
(state =3D=3D AFTER_MACROSTEP &amp;&amp; =
session.configuration.in('foo'))<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>session.receive('bar.baz');<br =
class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br =
class=3D"">
} catch (Exception e) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print =
e;<br class=3D"">
}<br class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D"">Here are my comments on =
this.</div><div style=3D"font-family: -apple-system-font; line-height: =
16px; direction: ltr;" class=3D""><br class=3D""></div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D""><div class=3D"">In SCION, there=E2=80=99s a notion of =
compiling the SCXML into a =E2=80=9Cmodel=E2=80=9D object, which is a =
native object used to create the session (<a =
href=3D"https://github.com/jbeard4/SCION#scxmlurltomodelurlfunctionerr-mod=
el" class=3D"">scxml.urlToModel</a>). This gives the client a way to =
create multiple sessions without reparsing/recompiling the SCXML into =
its object representation, which is a relatively expensive =
operation.&nbsp;</div><div class=3D""><br class=3D""></div><div =
class=3D"">Additionally, the model can be can be parsed from a DOM =
object (<a =
href=3D"https://github.com/jbeard4/SCION#scxmldocumenttomodelscxmldocument=
functionerr-model" class=3D"">scxml.documentToModel</a>), which provides =
opportunities for model transformation using XML DOM API. Finally, in =
SCION there are convenience methods for parsing SCXML from filesystem =
(<a =
href=3D"https://github.com/jbeard4/SCION#scxmlpathtomodelpathfunctionerr-m=
odel" class=3D"">scxml.pathToModel</a>), and from a string =
representation (<a =
href=3D"https://github.com/jbeard4/SCION#scxmldocumentstringtomodelscxmldo=
cstringfunctionerr-model" =
class=3D"">scxml.documentStringToModel</a>).</div><div class=3D""><br =
class=3D""></div><div class=3D"">After that, can you instantiate the =
session using the model object: scxml.scion.Statechart(model, =
options)</div><div class=3D""><br class=3D""></div><div class=3D"">It=E2=80=
=99s useful to have a mechanism to specify the SCXML _sessionid. This is =
passed in on the options argument.</div><div class=3D""><br =
class=3D""></div><div class=3D"">session.step() seems equivalent to =
session.start() in SCION. This causes the state machine to enter its =
initial state.</div><div class=3D""><br class=3D""></div><div =
class=3D"">Currently in SCION, the return value of session.start() is a =
basic configuration (set of basic states), encoded as a JavaScript array =
containing state id strings. In SCION, the basic configuration is kept =
as an internal data structure, so this cheap to return.&nbsp;</div><div =
class=3D""><br class=3D""></div><div class=3D"">In terms of querying the =
session for current state, you can use session.getConfiguration() to get =
the basic configuration, and use regular JavaScript semantics to query =
the array (e.g. "configuration.indexOf(=E2=80=99stateId') &gt; -1=E2=80=9D=
). You can a can also use session.isIn(=E2=80=99stateId') to query the =
session for basic and composite states.</div><div class=3D""><br =
class=3D""></div><div class=3D"">In SCION, session.gen() is equivalent =
to session.receive(). I chose the name =E2=80=9Cgen" from Harel=E2=80=99s =
paper&nbsp;<a =
href=3D"http://research.microsoft.com/apps/pubs/default.aspx?id=3D148785" =
class=3D"">The Rhapsody Semantics of Statecharts</a>. In SCION, the =
return value is the same as session.start(): a basic =
configuration.</div><div class=3D""><br class=3D""></div><div =
class=3D"">Finally, you can use session.isFinal() to check if the =
session is in a final state.</div><div class=3D""><br =
class=3D""></div><div class=3D"">Altogether, here is an example of the =
SCION API:</div><div class=3D""><br class=3D""></div><div class=3D""><pre =
style=3D"box-sizing: border-box; overflow: auto; font-family: Consolas, =
'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; =
margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; =
background-color: rgb(247, 247, 247); border-top-left-radius: 3px; =
border-top-right-radius: 3px; border-bottom-right-radius: 3px; =
border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal; =
color: rgb(51, 51, 51);" class=3D"">    scxml.urlToModel(url,<span =
class=3D"pl-k" style=3D"box-sizing: border-box; color: rgb(167, 29, =
93);">function</span>(<span class=3D"pl-smi" style=3D"box-sizing: =
border-box;">err</span>, <span class=3D"pl-smi" style=3D"box-sizing: =
border-box;">model</span>){

        <span class=3D"pl-k" style=3D"box-sizing: border-box; color: =
rgb(167, 29, 93);">if</span>(err) <span class=3D"pl-k" =
style=3D"box-sizing: border-box; color: rgb(167, 29, 93);">throw</span> =
err;

        <span class=3D"pl-c" style=3D"box-sizing: border-box; color: =
rgb(150, 152, 150);">//you can inspect the generated code if you like =
using JavaScript's Function.prototype.toString</span>
        <span class=3D"pl-en" style=3D"box-sizing: border-box; color: =
rgb(121, 93, 163);">console</span><span class=3D"pl-c1" =
style=3D"box-sizing: border-box; color: rgb(0, 134, =
179);">.log</span>(model.<span class=3D"pl-c1" style=3D"box-sizing: =
border-box; color: rgb(0, 134, 179);">toString</span>());      =20

        <span class=3D"pl-c" style=3D"box-sizing: border-box; color: =
rgb(150, 152, 150);">//instantiate the interpreter</span>
        <span class=3D"pl-k" style=3D"box-sizing: border-box; color: =
rgb(167, 29, 93);">var</span> statechart1 <span class=3D"pl-k" =
style=3D"box-sizing: border-box; color: rgb(167, 29, 93);">=3D</span> =
<span class=3D"pl-k" style=3D"box-sizing: border-box; color: rgb(167, =
29, 93);">new</span> <span class=3D"pl-en" style=3D"box-sizing: =
border-box; color: rgb(121, 93, =
163);">scxml.scion</span>.Statechart(model);

        <span class=3D"pl-c" style=3D"box-sizing: border-box; color: =
rgb(150, 152, 150);">//you can instantiate a second interpreter using =
the same model</span>
        <span class=3D"pl-k" style=3D"box-sizing: border-box; color: =
rgb(167, 29, 93);">var</span> statechart2 <span class=3D"pl-k" =
style=3D"box-sizing: border-box; color: rgb(167, 29, 93);">=3D</span> =
<span class=3D"pl-k" style=3D"box-sizing: border-box; color: rgb(167, =
29, 93);">new</span> <span class=3D"pl-en" style=3D"box-sizing: =
border-box; color: rgb(121, 93, =
163);">scxml.scion</span>.Statechart(model);

        <span class=3D"pl-c" style=3D"box-sizing: border-box; color: =
rgb(150, 152, 150);">//start the interpreter</span>
        <span class=3D"pl-k" style=3D"box-sizing: border-box; color: =
rgb(167, 29, 93);">var</span> initialConfiguration <span class=3D"pl-k" =
style=3D"box-sizing: border-box; color: rgb(167, 29, 93);">=3D</span> =
statechart1.<span class=3D"pl-c1" style=3D"box-sizing: border-box; =
color: rgb(0, 134, 179);">start</span>();

        <span class=3D"pl-c" style=3D"box-sizing: border-box; color: =
rgb(150, 152, 150);">//send events</span>
        statechart1.gen({name <span class=3D"pl-k" style=3D"box-sizing: =
border-box; color: rgb(167, 29, 93);">:</span> <span class=3D"pl-s" =
style=3D"box-sizing: border-box; color: rgb(24, 54, 145);"><span =
class=3D"pl-pds" style=3D"box-sizing: border-box;">'</span>foo<span =
class=3D"pl-pds" style=3D"box-sizing: border-box;">'</span></span>, data =
<span class=3D"pl-k" style=3D"box-sizing: border-box; color: rgb(167, =
29, 93);">:</span> <span class=3D"pl-s" style=3D"box-sizing: border-box; =
color: rgb(24, 54, 145);"><span class=3D"pl-pds" style=3D"box-sizing: =
border-box;">'</span>bar<span class=3D"pl-pds" style=3D"box-sizing: =
border-box;">'</span></span>});
    });</pre><div class=3D""><br class=3D""></div></div></div></div><br =
class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div =
style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D"">
A couple of notes and possible variations:<br class=3D"">
<br class=3D"">
=3D=3D 1. Threads<br class=3D"">
I want to avoid any assumptions about the availability of threads in the =
embedding platform. As such, there is e.g. no non-blocking interpret(). =
It would be the responsibility of the target platform to emulate =
something like this by embedding the block above&nbsp;in
 a thread.<br class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><span style=3D"font-family: -apple-system-font; =
line-height: 16px;" class=3D"">I agree with this. A blocking API for =
interpret/receive/gen works well with the notion of =E2=80=9CFast =
Computation=E2=80=9D for big-step modeling languages described in =
section 2.3 of&nbsp;</span><a =
href=3D"https://cs.uwaterloo.ca/~sesmaeil/publications/2009/CS-2009-05.pdf=
" style=3D"font-family: -apple-system-font; line-height: 16px;" =
class=3D"">Big-Step Semantics</a><span style=3D"font-family: =
-apple-system-font; line-height: 16px;" class=3D"">&nbsp;by Nancy Day, =
et al. gen() should be a fast, synchronous, blocking =
operation.</span></div><br class=3D""><blockquote type=3D"cite" =
class=3D""><div class=3D""><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D"">
=3D=3D 2. Exceptions<br class=3D"">
Similarly I want to avoid any assumption about the availability of =
exceptions, therefore step() might return FAULT and set the lastError =
attribute:<br class=3D"">
<br class=3D"">
int state;<br class=3D"">
for(;;) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>state - =
session.step();<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>switch(state) {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case =
FAULT:<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print =
session.lastError;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br =
class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case =
FINISHED:<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>return;<br=
 class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br =
class=3D"">
}<br class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><span style=3D"font-family: -apple-system-font; =
line-height: 16px;" class=3D"">I=E2=80=99ve been considering this. The =
SCXML spec says that scripting errors should be put on the internal =
queue as error.execution events. However, from a developer perspective, =
I often find this behavior surprising. The developer needs to remember =
to add a top-level &lt;transition event=3D=E2=80=9Cerror.*=E2=80=9D&gt; =
to catch execution errors exposed as events. So by default, in SCXML, =
JavaScript errors are suppressed. I therefore think it could be useful =
if the interpreter API could provide better visibility so that execution =
errors are by default not suppressed.&nbsp;</span></div><div><br =
class=3D""></div><br class=3D""><blockquote type=3D"cite" class=3D""><div =
class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: =
space; -webkit-line-break: after-white-space;" class=3D"">
=3D=3D 3. Data<br class=3D"">
0. If nothing in a Data object is set, its value is undefined<br =
class=3D"">
1. If an atom is given, the respective field is to be interpreted as the =
evaluation of that atom, e.g. "3" is a string, 3 is an integer.<br =
class=3D"">
2. If a node is given and 1. is not the case, the field is to be =
represented as a DOM Node<br class=3D"">
3. If a key in a compound is set and 1. and 2. are not the case, the =
respective field is a map<br class=3D"">
4. If an index is set and none of the above applies, the respective =
field is an array. Setting a an item at an index N will cause the array =
to behave as if it has N fields for the largest N. With all unset fields =
undefined.<br class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><span style=3D"font-family: -apple-system-font; =
line-height: 16px;" class=3D"">In SCION, the datamodel is kept fully =
private, and not exposed externally, except via the =
session.getSnapshot() method, which returns a copy of the full =
datamodel. This is a relatively cheap operation.</span></div><br =
class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div =
style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D"">
=3D=3D 4. Event<br class=3D"">
Having most fields visible will allow for interpreters where all i/o =
processors are external by simply delivering respective Event entities =
via receive. The distinction between internal and external events ought =
to happen in receive(Event) itself depending
 on&nbsp;the event's type field. I am not sure if we need the PLATFORM =
class though.<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><span style=3D"font-family: -apple-system-font; =
line-height: 16px;" class=3D"">I agree that receive() should be able to =
accommodate both internal and external events. It should be possible to =
inspect the _event.origin field and compare it to _ioprocessors to =
determine whether an event originating internal or external to the =
session.</span></div><div><font face=3D"-apple-system-font" =
class=3D""><span style=3D"line-height: 16px;" class=3D""><br =
class=3D""></span></font><blockquote type=3D"cite" class=3D""><div =
class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: =
space; -webkit-line-break: after-white-space;" class=3D"">
<br class=3D"">
=3D=3D 5. Hibernating<br class=3D"">
We might want to include a way to serialise a complete interpreter and =
instantiate it again from its serialised representation. I do know that =
Jacob was working on a respective feature. We dropped our ambitions for =
now as most of the datamodels we&nbsp;employed
 via 3rd party libraries would not support something like that.<br =
class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D"">Right now, in SCION, =
datamodel elements that are =E2=80=9Ctransient=E2=80=9D (not =
serializable) are initialized in the top-level &lt;script&gt; tag, which =
is executed every time a session is instantiated. Rather than put them =
in the datamodel, they are declared in the &lt;script&gt; tag using =
JavaScript =E2=80=9Cvar=E2=80=9D. I think this is a bit ugly, and could =
be improved. To improve this, two things would be needed:</div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D""><br class=3D""></div><div style=3D"font-family: =
-apple-system-font; line-height: 16px; direction: ltr;" class=3D"">1. An =
explicit notion of transient attributes on the datamodel. This is =
similar to the =E2=80=9Ctransient" attribute modifier in Java. These =
datamodel elements would not be serialized on hibernate.</div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D"">2. Explicitly recognizing that top-level script tag is =
a code block that will executed on resume. This allows transient =
datamodel elements to be re-initialized.&nbsp;</div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D""><br class=3D""></div><div style=3D"font-family: =
-apple-system-font; line-height: 16px; direction: ltr;" class=3D"">State =
machine hibernation is useful for developing scalable cloud =
applications, as it allows your SCXML session data to be persisted to =
secondary storage, rather than kept in memory. This is needed for =
horizontal scalability.</div></div><br class=3D""><blockquote =
type=3D"cite" class=3D""><div class=3D""><div style=3D"word-wrap: =
break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D"">
=3D=3D 6. Naming<br class=3D"">
AFTER_MACROSTEP might just as well be called STABLE. I choose the former =
for its more explicit reference to the runtime semantics of SCXML, which =
might play a role if we were to specify a bunch of hooks for 1.2 and 1.3 =
(see debugger paper[1], table&nbsp;1)<br class=3D"">
<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D"">I think it would be =
useful to explicitly capture these interpreter states as a meta-state =
machine.</div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D""><br class=3D""></div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D"">It may be interesting to look at the states in the =
docker container lifecycle, as docker provides a generic container API =
for linux applications. These concepts could carry over to modeling the =
SCXML interpreter lifecycle. I created an SCXML to model this =
here:&nbsp;<a href=3D"http://examples.scxml.io/e/docker-manager/" =
class=3D"">http://examples.scxml.io/e/docker-manager/</a></div></div><br =
class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div =
style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D"">
=3D=3D 7. Events *from* the interpreter<br class=3D"">
While point 4 allows an embedding platform to send arbitrary events =
*into* the interpreter, maybe we ought to have something similar for =
everything &lt;send&gt; from the interpreter?<br class=3D"">
<br class=3D""></div></div></blockquote><div><br class=3D""></div><span =
style=3D"font-family: -apple-system-font; line-height: 16px;" class=3D"">I=
 think we should consider an API for &lt;send&gt;. I=E2=80=99m currently =
working on improving the SCION &lt;send&gt; implementation, including =
support for custom send types, and will follow up on this item =
shortly.</span></div><div><font face=3D"-apple-system-font" =
class=3D""><span style=3D"line-height: 16px;" class=3D""><br =
class=3D""></span></font><blockquote type=3D"cite" class=3D""><div =
class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: =
space; -webkit-line-break: after-white-space;" class=3D"">
<br class=3D"">
Maybe anyone who is interested in pursuing the idea of this basic IDL =
could speak up and comment about the proposal? What is missing, what is =
superfluous for a basic IDL?<br =
class=3D""></div></div></blockquote><div><br class=3D""></div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D"">Thank you for getting this process started. Please let =
me know your feedback, and I can take a pass at iterating on the =
proposed IDL.</div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D""><br class=3D""></div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D"">Regards,</div><div style=3D"font-family: =
-apple-system-font; line-height: 16px; direction: ltr;" class=3D""><br =
class=3D""></div><div style=3D"font-family: -apple-system-font; =
line-height: 16px; direction: ltr;" class=3D"">Jacob Beard</div><div =
style=3D"font-family: -apple-system-font; line-height: 16px; direction: =
ltr;" class=3D""><br class=3D""></div><blockquote type=3D"cite" =
class=3D""><div class=3D""><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D"">
<br class=3D"">
Regards<br class=3D"">
Stefan<br class=3D"">
<br class=3D"">
[1] <a =
href=3D"http://scxmlworkshop.de/eics2014/submissions/A%20Debugger%20for%20=
SCXML%20Documents.pdf" =
class=3D"">http://scxmlworkshop.de/eics2014/submissions/A%20Debugger%20for=
%20SCXML%20Documents.pdf</a><br class=3D"">
<br class=3D"">
<br class=3D"">
<br class=3D"">
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br class=3D"">
<br class=3D"">
<font face=3D"Courier" class=3D"">module scxml {<br class=3D"">
<br class=3D"">
exception Exception {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short PARSE_ERR =3D 1; // Given string could not be parsed as =
an xml document<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short SCHEMA_ERR =3D 2; // XML DOM not a valid SCXML =
document<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short IMPL_ERR =3D 4; // Unknown datamodel, ioproc, executable =
content or invoker used<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>unsigned =
short code;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
cause;<br class=3D"">
};<br class=3D"">
<br class=3D"">
<br class=3D"">
// central place to get interpreter instances<br class=3D"">
interface Implementation {<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>Interpreter fromURI(in String uri) =
raises(Exception);<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>Interpreter fromXML(in String =
xmlString) raises(Exception);<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>Interpreter fromDOM(in Node scxmlRoot) =
raises(Exception);<br class=3D"">
}<br class=3D"">
<br class=3D"">
interface Event {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short PLATFORM_EVENT &nbsp;=3D 1;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short INTERNAL_EVENT &nbsp;=3D 2;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned short EXTERNAL_EVENT &nbsp;=3D 3;<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
name;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>unsigned =
short type;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
origin;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
originType;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
sendid;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data =
data;<br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Data {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>set(in =
String value); // atom<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
get();<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>setNode(in=
 Node node); // XML node<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Node =
getNode();<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>setKey(in =
String key, in Data value); // compound<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data =
getKey(in String key);<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"></span>setItemAt(in String index, in Data =
value); // array<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>Data =
getItemAt(in String index);<br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Configuration {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>boolean =
in(in String state);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>String =
item(in unsigned long index);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly =
attribute unsigned long length;<br class=3D"">
};<br class=3D"">
<br class=3D"">
interface Interpreter {<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int FAULT =3D 0; // something bad happened, look into =
lastError<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int AFTER_MICROSTEP =3D 1; // step finished with a single =
microstep<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int AFTER_MACROSTEP =3D 2; // step finished with a single =
macrostep and interpreter is stable<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int SCXML_IDLE =3D 3; // interpreter is stable with no pending =
events on queues<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int SCXML_FINISHED =3D 4; // interpreter reached top-level =
final state<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int step() raises(Exception) raises(Exception); // blocking per =
default<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>const =
unsigned int step(in int timeOutMs) raises(Exception); // block at most =
for given duration, 0 for non-blocking<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>receive(in=
 Event event);<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>receive(in=
 String event); // convenience<br class=3D"">
<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly =
attribute Exception lastError;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly =
attribute Configuration configuration;<br class=3D"">
<span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>readonly =
attribute Configuration basicConfiguration;<br class=3D"">
}<br class=3D"">
}<br class=3D"">
</font><br class=3D"">
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</div>

</div></blockquote></div><br class=3D""></body></html>=

--Apple-Mail=_21B62C63-F893-4F3D-B1C3-F2DAFA8685F6--