Re: SCXML2 Serialization
Hi Francis, Thanks for the example test code, it helped me detect a bug in the state machine running status management which I already fixed, see [1]. Can you test and verify this now works for you? (note: you'll have to use SCXML trunk). I've one more comment inline below. Regards, Ate [1] https://issues.apache.org/jira/browse/SCXML-202 On 16-04-14 22:14, ten...@free.fr wrote: Thanks for your reply Ate. I want to serialize/deserialize a SCXML 'session' for this use case : Into a transactional server, a request is processed by a thread. An ID is retrieved from the message, with this ID the server loads a context (from a redis store) and instantiates a new 'Executor' with it's associated SCXML file and saved instance. I'll use invokers to call external functions or new a SCXML 'processor', I don't expect them to still be running after the state machine stabilized. You said : But then you should not set the statemachine again (after attachInstance) as that will re-initialize the SCInstance itself so I don't have to do this executor.setStateMachine(scxml);because scxml is serialized with the scInstance. But if I need to register a listener (addListener) or if I have custom actions, are they serialized too? No, SCXMLListeners are also not serialized. The reasoning for this is that, like with the Invokers, and all other interface based injected external objects, there is no way to determine and detect what they might end up serializing, if even possible. And they might be referenced themselves by other non-serialized objects which 'reference link' would get borked and broken after de-serialization. So you'll have to re-register listeners again as well. That is just the only save and stable way to do this. Note: the SCXMLListeners are 'registered' on the internal SCXML element id's and not the serialized elements themselves, so if you would not have to re-create SCXMLExecutor, *then* there is no need to re-register anything. In the example I do 'setInitialState(executor, paused);' because the call to go resets the state and I know that 'paused' is the last state. Of course I want to 'return' in the same state I left off. Without a call of the go function, the state machine seems to be frozen. That was because of the bug I now fixed. AFAIK the example code you provided now 'works'. Thanks, Regards Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
SCXML2 Serialization
Hi Ate It's ok : Loading simple1 Deserialize.. After creation [startIngTrs.processMsg is running : true message:message2 serialize.. Process finished with exit code 0 Thanks Regards, Francis. On Fri, Apr 18, 2014 at 2:12 PM, Ate Douma a...@douma.nu wrote: Hi Francis, Thanks for the example test code, it helped me detect a bug in the state machine running status management which I already fixed, see [1]. Can you test and verify this now works for you? (note: you'll have to use SCXML trunk). I've one more comment inline below. Regards, Ate [1] https://issues.apache.org/jira/browse/SCXML-202 On 16-04-14 22:14, ten...@free.fr wrote: Thanks for your reply Ate. I want to serialize/deserialize a SCXML 'session' for this use case : Into a transactional server, a request is processed by a thread. An ID is retrieved from the message, with this ID the server loads a context (from a redis store) and instantiates a new 'Executor' with it's associated SCXML file and saved instance. I'll use invokers to call external functions or new a SCXML 'processor', I don't expect them to still be running after the state machine stabilized. You said : But then you should not set the statemachine again (after attachInstance) as that will re-initialize the SCInstance itself so I don't have to do this executor.setStateMachine(scxml);because scxml is serialized with the scInstance. But if I need to register a listener (addListener) or if I have custom actions, are they serialized too? No, SCXMLListeners are also not serialized. The reasoning for this is that, like with the Invokers, and all other interface based injected external objects, there is no way to determine and detect what they might end up serializing, if even possible. And they might be referenced themselves by other non-serialized objects which 'reference link' would get borked and broken after de-serialization. So you'll have to re-register listeners again as well. That is just the only save and stable way to do this. Note: the SCXMLListeners are 'registered' on the internal SCXML element id's and not the serialized elements themselves, so if you would not have to re-create SCXMLExecutor, *then* there is no need to re-register anything. In the example I do 'setInitialState(executor, paused);' because the call to go resets the state and I know that 'paused' is the last state. Of course I want to 'return' in the same state I left off. Without a call of the go function, the state machine seems to be frozen. That was because of the bug I now fixed. AFAIK the example code you provided now 'works'. Thanks, Regards Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
Re: SCXML2 Serialization
Hi Francis, On 17-04-14 07:48, ten...@free.fr wrote: Hi Ate, I put Simple1.java and Simple1.xml here : http://tendaf.free.fr/ I'll try to make some time tomorrow to test drive your example. Regards, Ate When I run the program (second time) the fsm is frozen : First time : After creation [startIngTrs.processMsg is running : true message:message1 serialize.. Process finished with exit code 0 Second time : Loading simple1 Deserialize.. After creation [startIngTrs.waitMsg is running : false message:message2 Process finished with exit code 0 Thanks, Regards Francis. Thanks for your reply Ate. I want to serialize/deserialize a SCXML 'session' for this use case : Into a transactional server, a request is processed by a thread. An ID is retrieved from the message, with this ID the server loads a context (from a redis store) and instantiates a new 'Executor' with it's associated SCXML file and saved instance. I'll use invokers to call external functions or new a SCXML 'processor', I don't expect them to still be running after the state machine stabilized. You said : But then you should not set the statemachine again (after attachInstance) as that will re-initialize the SCInstance itself so I don't have to do this executor.setStateMachine(scxml);because scxml is serialized with the scInstance. But if I need to register a listener (addListener) or if I have custom actions, are they serialized too? In the example I do 'setInitialState(executor, paused);' because the call to go resets the state and I know that 'paused' is the last state. Of course I want to 'return' in the same state I left off. Without a call of the go function, the state machine seems to be frozen. Thanks, Regards Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
SCXML2 Serialization
Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.go(); setInitialState(executor, paused); } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? Thanks Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
Re: SCXML2 Serialization
Hi Francis, I think the best practices are to serialize either o.a.c.s.SCXMLExecutor [1] or o.a.c.s.model.SCXML instances. Both cases are well-maintained in test code. [2] In your case, you can probably (de)serialize SCXMLExecutor instance directly to store/load the execution context. Also, as far as I can see, SCXMLExecutor doesn't provide #(at|de)tachInstance() methods and I don't think it would do even later because SCInstance doesn't necessarily have full information about the current execution context. So, please (de)serialize the SCXMLExecutor instance instead. Cheers, Woonsan [1] http://commons.apache.org/proper/commons-scxml/faq.html#serializability [2] http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java On Wednesday, April 16, 2014 9:07 AM, ten...@free.fr ten...@free.fr wrote: Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.go(); setInitialState(executor, paused); } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? Thanks Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
Re: SCXML2 Serialization
Hi Francis, There are a few things not right or needed in your approach below. I've provided comments inline. On 16-04-14 15:07, ten...@free.fr wrote: Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); While you can recreate SCXMLExecutor each time, this is not the intended usage. The SCXMLExecutor holds the external event queue. If you are using Invokers, and you *do* in your example, then these might still be (kept) 'running' while the state machine itself is currently stabilized. So after a return from go() or triggerEvent(). And these invokers might send back events into the external queue for further processing. So then you should keep hold of the SCXMLExecutor instance, across serialization/deserialization of the SCInstance. If you don't use Invokers, or don't expect them to still be running after the state machine stabilized (which might be the case in your example?) then I guess recreating the SCXMLExecutor is fine. But then you should not set the statemachine again (after attachIstance) as that will re-initialize the SCInstance itself. Same goes for calling go() again or otherwise re-initializing the current state. What would be the point of serializing in that case anyway? Note also, the statemachine is automatically serialized together with the SCInstance, so you actually don't need to set it again. if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); this shouldn't be done as it will re-initialize the SCInstance state executor.go(); this does the same, so definitely shouldn't be done either, because this way there is no 'state' retained from what you serialized before setInitialState(executor, paused); same goes for this: if you re-attach the instance, I assume you would want to 'return' in the same state you left off, right? } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); This initialization part is fine } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? See comments above. You're almost good but especially need to think about the Invoker use-cases and if that might require you to keep hold of the SCXMLExecutor instance. Regards, Ate Thanks Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
Re: SCXML2 Serialization
Hi Woonsan, On 16-04-14 15:49, Woonsan Ko wrote: Hi Francis, I think the best practices are to serialize either o.a.c.s.SCXMLExecutor [1] or o.a.c.s.model.SCXML instances. Both cases are well-maintained in test code. [2] Actually, since the last milestone SCXMLExecutor no longer is serializable :) See also https://issues.apache.org/jira/browse/SCXML-197 I still need to provide updated documentation for this, but the SCXMLTestHelper [2] class has been (and had to be) updated for this changed usage. In your case, you can probably (de)serialize SCXMLExecutor instance directly to store/load the execution context. Also, as far as I can see, SCXMLExecutor doesn't provide #(at|de)tachInstance() methods and I don't think it would do even later because SCInstance doesn't necessarily have full information about the current execution context. So, please (de)serialize the SCXMLExecutor instance instead. You need to update to the latest milestone 1 or trunk, then you'll see the new attach/detach instance features ;) Cheers, Woonsan [1] http://commons.apache.org/proper/commons-scxml/faq.html#serializability [2] http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java On Wednesday, April 16, 2014 9:07 AM, ten...@free.fr ten...@free.fr wrote: Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.go(); setInitialState(executor, paused); } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? Thanks Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
Re: SCXML2 Serialization
On Wednesday, April 16, 2014 9:57 AM, Ate Douma a...@douma.nu wrote: Hi Woonsan, On 16-04-14 15:49, Woonsan Ko wrote: Hi Francis, I think the best practices are to serialize either o.a.c.s.SCXMLExecutor [1] or o.a.c.s.model.SCXML instances. Both cases are well-maintained in test code. [2] Actually, since the last milestone SCXMLExecutor no longer is serializable :) See also https://issues.apache.org/jira/browse/SCXML-197 I still need to provide updated documentation for this, but the SCXMLTestHelper [2] class has been (and had to be) updated for this changed usage. In your case, you can probably (de)serialize SCXMLExecutor instance directly to store/load the execution context. Also, as far as I can see, SCXMLExecutor doesn't provide #(at|de)tachInstance() methods and I don't think it would do even later because SCInstance doesn't necessarily have full information about the current execution context. So, please (de)serialize the SCXMLExecutor instance instead. You need to update to the latest milestone 1 or trunk, then you'll see the new attach/detach instance features ;) Ah, sorry. I haven't updated the code for a while. My comment was based on outdated information then.. Thanks, Woonsan Cheers, Woonsan [1] http://commons.apache.org/proper/commons-scxml/faq.html#serializability [2] http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java On Wednesday, April 16, 2014 9:07 AM, ten...@free.fr ten...@free.fr wrote: Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.go(); setInitialState(executor, paused); } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? Thanks Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org
RE: SCXML2 Serialization
Thanks for your reply Ate. I want to serialize/deserialize a SCXML 'session' for this use case : Into a transactional server, a request is processed by a thread. An ID is retrieved from the message, with this ID the server loads a context (from a redis store) and instantiates a new 'Executor' with it's associated SCXML file and saved instance. I'll use invokers to call external functions or new a SCXML 'processor', I don't expect them to still be running after the state machine stabilized. You said : But then you should not set the statemachine again (after attachInstance) as that will re-initialize the SCInstance itself so I don't have to do this executor.setStateMachine(scxml);because scxml is serialized with the scInstance. But if I need to register a listener (addListener) or if I have custom actions, are they serialized too? In the example I do 'setInitialState(executor, paused);' because the call to go resets the state and I know that 'paused' is the last state. Of course I want to 'return' in the same state I left off. Without a call of the go function, the state machine seems to be frozen. Thanks, Regards Francis. -- Hi Francis, There are a few things not right or needed in your approach below. I've provided comments inline. On 16-04-14 15:07, ten...@free.fr wrote: Hi all, I would like to know the best practice to serialize/deserialize SCXML fsm. I do this during the creation of the SCXML executor, scInstace is the serialized context: ListCustomAction customActions = new ArrayListCustomAction(); CustomAction ca = new CustomAction(http://my.custom-actions.domain/CUSTOM1;, hello, Hello.class); customActions.add(ca); JexlEvaluator evaluator = new JexlEvaluator(); try { scxml = SCXMLReader.read(StopWatch.class.getClassLoader(). } catch (Exception e) { e.printStackTrace(); throw e; } executor = null; try { executor = new SCXMLExecutor(evaluator, null, new SimpleErrorReporter()); While you can recreate SCXMLExecutor each time, this is not the intended usage. The SCXMLExecutor holds the external event queue. If you are using Invokers, and you *do* in your example, then these might still be (kept) 'running' while the state machine itself is currently stabilized. So after a return from go() or triggerEvent(). And these invokers might send back events into the external queue for further processing. So then you should keep hold of the SCXMLExecutor instance, across serialization/deserialization of the SCInstance. If you don't use Invokers, or don't expect them to still be running after the state machine stabilized (which might be the case in your example?) then I guess recreating the SCXMLExecutor is fine. But then you should not set the statemachine again (after attachIstance) as that will re-initialize the SCInstance itself. Same goes for calling go() again or otherwise re-initializing the current state. What would be the point of serializing in that case anyway? Note also, the statemachine is automatically serialized together with the SCInstance, so you actually don't need to set it again. if (scInstance != null) { // serialized context use it executor.attachInstance(scInstance); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); this shouldn't be done as it will re-initialize the SCInstance state executor.go(); this does the same, so definitely shouldn't be done either, because this way there is no 'state' retained from what you serialized before setInitialState(executor, paused); same goes for this: if you re-attach the instance, I assume you would want to 'return' in the same state you left off, right? } else { // new context Context rootContext = new JexlContext(); rootContext.set(var1, value1); executor.registerInvokerClass(x-test, DummyInvoker.class); executor.setStateMachine(scxml); executor.setRootContext(rootContext); executor.go(); This initialization part is fine } } catch (ModelException me) { // Executor initialization failed, because the // state machine specified has inconsistencies me.printStackTrace(); } I serialize executor.detachInstance(). It's seem to work, but is it the right way to restart a SCXML 'session' ? See comments above. You're almost good but especially need to think about the Invoker use-cases and if that might require you to
SCXML2 Serialization
Hi Ate, I put Simple1.java and Simple1.xml here : http://tendaf.free.fr/ When I run the program (second time) the fsm is frozen : First time : After creation [startIngTrs.processMsg is running : true message:message1 serialize.. Process finished with exit code 0 Second time : Loading simple1 Deserialize.. After creation [startIngTrs.waitMsg is running : false message:message2 Process finished with exit code 0 Thanks, Regards Francis. Thanks for your reply Ate. I want to serialize/deserialize a SCXML 'session' for this use case : Into a transactional server, a request is processed by a thread. An ID is retrieved from the message, with this ID the server loads a context (from a redis store) and instantiates a new 'Executor' with it's associated SCXML file and saved instance. I'll use invokers to call external functions or new a SCXML 'processor', I don't expect them to still be running after the state machine stabilized. You said : But then you should not set the statemachine again (after attachInstance) as that will re-initialize the SCInstance itself so I don't have to do this executor.setStateMachine(scxml);because scxml is serialized with the scInstance. But if I need to register a listener (addListener) or if I have custom actions, are they serialized too? In the example I do 'setInitialState(executor, paused);' because the call to go resets the state and I know that 'paused' is the last state. Of course I want to 'return' in the same state I left off. Without a call of the go function, the state machine seems to be frozen. Thanks, Regards Francis. - To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org