Last active
October 20, 2017 13:58
-
-
Save kenwebb/834e367697da821ca2b207552f761018 to your computer and use it in GitHub Desktop.
Sync vs Async
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Fri Oct 20 2017 09:58:26 GMT-0400 (EDT)--> | |
<XholonWorkbook> | |
<Notes><![CDATA[ | |
Xholon | |
------ | |
Title: Sync vs Async | |
Description: | |
Url: http://www.primordion.com/Xholon/gwt/ | |
InternalName: 834e367697da821ca2b207552f761018 | |
Keywords: | |
My Notes | |
-------- | |
sync = synchronous interaction = a functional approach | |
async = asynchronous interaction = a non-functional approach | |
What is the accepted name for the non-functional approach? | |
- this is the standard approach in ROOM/ObjecTime/eTrice/Xholon | |
In this workbook, I will write the same app using both of these approaches. | |
The app will perform a number of arithmetic calculations, and will produce a single result. | |
The sync approach will use Xholon synchronous messaging. | |
The async approach will use Xholon asynchronous messaging. | |
(((3 + 2) * 6) - (7 + 1)) | |
]]></Notes> | |
<_-.XholonClass xmlns:xi="http://www.w3.org/2001/XInclude"> | |
<PhysicalSystem/> | |
<ArithFunc> | |
<!-- a function that adds 2 numbers --> | |
<AddFunc superClass="Script"/> | |
<!-- a function that subtracts 2 numbers --> | |
<SubFunc superClass="Script"/> | |
<!-- a function that multiplies 2 numbers --> | |
<MulFunc superClass="Script"/> | |
</ArithFunc> | |
<Functions/> | |
<!-- MathML Mechanism --> | |
<xi:include href="config/mech/mathml/MathMLEntity.xml"/> | |
<xi:include href="config/mech/mathml/MathML_ClassDetails.xml"/> | |
</_-.XholonClass> | |
<xholonClassDetails> | |
<AddFunc><DefaultContent> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
}, | |
processReceivedSyncMessage: function(msg) { | |
var data = msg.data; | |
me.println(data); | |
return data[0] + data[1]; | |
} | |
} | |
</DefaultContent></AddFunc> | |
<SubFunc><DefaultContent> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
}, | |
processReceivedSyncMessage: function(msg) { | |
var data = msg.data; | |
me.println(data); | |
return data[0] - data[1]; | |
} | |
} | |
</DefaultContent></SubFunc> | |
<MulFunc><DefaultContent> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
}, | |
processReceivedSyncMessage: function(msg) { | |
var data = msg.data; | |
me.println(data); | |
return data[0] * data[1]; | |
} | |
} | |
</DefaultContent></MulFunc> | |
</xholonClassDetails> | |
<PhysicalSystem> | |
<TestNullApproach implName="org.primordion.xholon.base.Behavior_gwtjs"> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
me.println("(((3 + 2) * 6) - (7 + 1)) = " + (((3 + 2) * 6) - (7 + 1))); | |
} | |
} | |
</TestNullApproach> | |
<TestMathmlApproach> | |
<math> | |
<apply> | |
<minus/> | |
<apply> | |
<times/> | |
<apply> | |
<plus/> | |
<cn>3</cn> | |
<cn>2</cn> | |
</apply> | |
<cn>6</cn> | |
</apply> | |
<apply> | |
<plus/> | |
<cn>7</cn> | |
<cn>1</cn> | |
</apply> | |
</apply> | |
</math> | |
</TestMathmlApproach> | |
<TestSyncApproach implName="org.primordion.xholon.base.Behavior_gwtjs"> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
me.println("(((3 + 2) * 6) - (7 + 1)) = " + (((3 + 2) * 6) - (7 + 1))); | |
me.addF = me.next().first(); | |
me.subF = me.addF.next(); | |
me.mulF = me.subF.next(); | |
}, | |
act: function() { | |
// 1 | |
var result1 = me.addF.call(101, [3,2], me); | |
me.println(result1.data); | |
$wnd.console.log(result1.data); | |
// 2 | |
var result2 = me.addF.call(101, [7,1], me); | |
me.println(result2.data); | |
$wnd.console.log(result2.data); | |
// 3 | |
var result3 = me.mulF.call(101, [result1.data, 6], me); | |
me.println(result3.data); | |
$wnd.console.log(result3.data); | |
// 4 | |
var result4 = me.subF.call(101, [result3.data, result2.data], me); | |
me.println(result4.data); | |
$wnd.console.log(result4.data); | |
} | |
} | |
</TestSyncApproach> | |
<!-- a set of functions | |
TestSyncApproach requires that this subtree be immediately after it | |
--> | |
<Functions> | |
<AddFunc/> | |
<SubFunc/> | |
<MulFunc/> | |
</Functions> | |
<!-- TODO this will probably be similar to a Petri Net (PN) | |
Processing is synchronized by waiting for all required values to be ready. | |
It should contain three sets: | |
- a set of functions | |
- a set of values (passive objects, Petri Net places) | |
- a set of synchronizing nodes (these call the functions, Petri Net transitions) | |
--> | |
<TestAsyncApproach implName="org.primordion.xholon.base.Behavior_gwtjs"> | |
var me, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
} | |
} | |
</TestAsyncApproach> | |
<!-- structure the problem as a Petri Net, but it won't do the correct calculations | |
(((3 + 2) * 6) - (7 + 1)) | |
--> | |
<TestPetriNetApproach> | |
<!-- KINETICS_CUSTOM = 6; use the PetriNetCusomProcessor node to do calculations --> | |
<PetriNet roleName="arithPN" kineticsType="6"> | |
<QueueTransitions/> | |
<Places> | |
<!-- initial values --> | |
<PlacePN roleName="p1" token="3"/> | |
<PlacePN roleName="p2" token="2"/> | |
<PlacePN roleName="p3" token="6"/> | |
<PlacePN roleName="p4" token="7"/> | |
<PlacePN roleName="p5" token="1"/> | |
<!-- intermediate values --> | |
<PlacePN roleName="p11"/> | |
<PlacePN roleName="p12"/> | |
<PlacePN roleName="p13"/> | |
<!-- final result value --> | |
<PlacePN roleName="p101"/> | |
</Places> | |
<Transitions> | |
<TransitionPN roleName="t1Add"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p1']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p2']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p11']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t2Add"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p4']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p5']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p12']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t3Mul"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p11']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p3']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p13']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t4Sub"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p13']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p12']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p101']"/> | |
</OutputArcs> | |
</TransitionPN> | |
</Transitions> | |
</PetriNet> | |
<PetriNetCustomProcessor implName="org.primordion.xholon.base.Behavior_gwtjs"> | |
var me, trns, funcs, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
me.println(me.name()); | |
trns = me.xpath("../PetriNet/Transitions/TransitionPN"); | |
funcs = me.xpath("../../Functions"); | |
}, | |
act: function() { | |
if (trns) { | |
me.println(trns.name()); | |
var inarcs = trns.first(); | |
var outarcs = inarcs.next(); | |
var inarc = inarcs.first(); | |
var inval1 = inarc.links(false,true)[0].reffedNode.val(); | |
var inval2 = inarc.next().links(false,true)[0].reffedNode.val(); | |
var outarc = outarcs.first(); | |
var func = null; | |
switch (trns.role()) { | |
case "t1Add": | |
case "t2Add": | |
func = funcs.xpath("AddFunc"); | |
break; | |
case "t3Mul": | |
func = funcs.xpath("MulFunc"); | |
break; | |
case "t4Sub": | |
func = funcs.xpath("SubFunc"); | |
break; | |
default: break; | |
} | |
var result = func.call(101, [inval1,inval2], me); | |
outarc.links(false,true)[0].reffedNode.val(result.data); | |
trns = trns.next(); | |
} | |
} | |
} | |
</PetriNetCustomProcessor> | |
</TestPetriNetApproach> | |
<TestPetriNetFuncApproach> | |
<!-- KINETICS_FUNCTION = 11; auto invoke functions --> | |
<PetriNet roleName="arithPN" kineticsType="11"> | |
<QueueTransitions shouldShuffle="false"/> | |
<Places> | |
<!-- initial values --> | |
<PlacePN roleName="p1" token="3"/> | |
<PlacePN roleName="p2" token="2"/> | |
<PlacePN roleName="p3" token="6"/> | |
<PlacePN roleName="p4" token="7"/> | |
<PlacePN roleName="p5" token="1"/> | |
<!-- intermediate values --> | |
<PlacePN roleName="p11"/> | |
<PlacePN roleName="p12"/> | |
<PlacePN roleName="p13"/> | |
<!-- final result value --> | |
<PlacePN roleName="p101"/> | |
</Places> | |
<Transitions> | |
<TransitionPN roleName="t1Add" functionXPath="ancestor::PhysicalSystem/Functions/AddFunc"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p1']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p2']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p11']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t2Add" functionXPath="ancestor::PhysicalSystem/Functions/AddFunc"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p4']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p5']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p12']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t3Mul" functionXPath="ancestor::PhysicalSystem/Functions/MulFunc"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p11']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p3']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p13']"/> | |
</OutputArcs> | |
</TransitionPN> | |
<TransitionPN roleName="t4Sub" functionXPath="ancestor::PhysicalSystem/Functions/SubFunc"> | |
<InputArcs> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p13']"/> | |
<InputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p12']"/> | |
</InputArcs> | |
<OutputArcs> | |
<OutputArc weight="1" connector="ancestor::PetriNet/Places/PlacePN[@roleName='p101']"/> | |
</OutputArcs> | |
</TransitionPN> | |
</Transitions> | |
</PetriNet> | |
</TestPetriNetFuncApproach> | |
<!-- | |
Capture interactions between nodes, and create a sequence diagram (also called a Message Sequence Chart (MSC)). | |
Once the code has run for one or more timesteps, click on View > Interactions . | |
The following (or something similar, should appear in a new tab: | |
title Sync vs Async | |
# To view sequence diagram, paste this text into http://www.websequencediagrams.com/ | |
# Created by: Xholon http://www.primordion.com/Xholon/ | |
# Date: 1508441050977 Thu Oct 19 15:24:10 GMT-400 2017 | |
testSyncApproach_62->addFunc_64: 3,2 | |
addFunc_64->testSyncApproach_62: 5 | |
testSyncApproach_62->addFunc_64: 7,1 | |
addFunc_64->testSyncApproach_62: 8 | |
testSyncApproach_62->mulFunc_66: 5,6 | |
mulFunc_66->testSyncApproach_62: 30 | |
testSyncApproach_62->subFunc_65: 30,8 | |
subFunc_65->testSyncApproach_62: 22 | |
petriNetCustomProcessor_106->addFunc_64: 3,2 | |
addFunc_64->petriNetCustomProcessor_106: 5 | |
testSyncApproach_62->addFunc_64: 3,2 | |
addFunc_64->testSyncApproach_62: 5 | |
testSyncApproach_62->addFunc_64: 7,1 | |
addFunc_64->testSyncApproach_62: 8 | |
testSyncApproach_62->mulFunc_66: 5,6 | |
mulFunc_66->testSyncApproach_62: 30 | |
testSyncApproach_62->subFunc_65: 30,8 | |
subFunc_65->testSyncApproach_62: 22 | |
petriNetCustomProcessor_106->addFunc_64: 7,1 | |
addFunc_64->petriNetCustomProcessor_106: 8 | |
testSyncApproach_62->addFunc_64: 3,2 | |
addFunc_64->testSyncApproach_62: 5 | |
testSyncApproach_62->addFunc_64: 7,1 | |
addFunc_64->testSyncApproach_62: 8 | |
testSyncApproach_62->mulFunc_66: 5,6 | |
mulFunc_66->testSyncApproach_62: 30 | |
testSyncApproach_62->subFunc_65: 30,8 | |
subFunc_65->testSyncApproach_62: 22 | |
petriNetCustomProcessor_106->mulFunc_66: 5,6 | |
mulFunc_66->petriNetCustomProcessor_106: 30 | |
testSyncApproach_62->addFunc_64: 3,2 | |
addFunc_64->testSyncApproach_62: 5 | |
testSyncApproach_62->addFunc_64: 7,1 | |
addFunc_64->testSyncApproach_62: 8 | |
testSyncApproach_62->mulFunc_66: 5,6 | |
mulFunc_66->testSyncApproach_62: 30 | |
testSyncApproach_62->subFunc_65: 30,8 | |
subFunc_65->testSyncApproach_62: 22 | |
petriNetCustomProcessor_106->subFunc_65: 30,8 | |
subFunc_65->petriNetCustomProcessor_106: 22 | |
Note: I manually deleteted the signal 101 from each line. | |
--> | |
<InteractionsViewer/> | |
</PhysicalSystem> | |
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml, | |
<!-- Generated by graphviz version 2.28.0 (20140111.2315) | |
--> | |
<!-- Title: PhysicalSystem Pages: 1 --> | |
<svg width="243pt" height="141pt" | |
viewBox="0.00 0.00 243.00 140.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<g id="PhysicalSystem" class="graph" transform="scale(1 1) rotate(0) translate(4 136.8)"> | |
<title>PhysicalSystem</title> | |
<polygon fill="white" stroke="none" points="-4,4 -4,-136.8 239,-136.8 239,4 -4,4"/> | |
<text text-anchor="middle" x="117.5" y="-8.2" font-family="Courier New" font-size="14.00">PhysicalSystem</text> | |
<!-- Test --> | |
<g id="PhysicalSystem/Test" class="node"><title>Test</title> | |
<polygon fill="#f0f8ff" stroke="black" points="126,-132.8 72,-132.8 72,-96.8 126,-96.8 126,-132.8"/> | |
<text text-anchor="middle" x="99" y="-110.6" font-family="Courier New" font-size="14.00">Test</text> | |
</g> | |
<!-- AddF --> | |
<g id="PhysicalSystem/Functions/AddF" class="node"><title>AddF</title> | |
<polygon fill="#f0f8ff" stroke="black" points="54,-60.8 0,-60.8 0,-24.8 54,-24.8 54,-60.8"/> | |
<text text-anchor="middle" x="27" y="-38.6" font-family="Courier New" font-size="14.00">AddF</text> | |
</g> | |
<!-- Test->AddF --> | |
<g id="PhysicalSystem_edge1" class="edge"><title>Test->AddF</title> | |
<path fill="none" stroke="black" d="M81.2022,-96.4966C72.396,-87.935 61.6179,-77.4562 51.9989,-68.1045"/> | |
<polygon fill="black" stroke="black" points="44.593,-60.9043 54.8999,-64.6487 48.178,-64.3897 51.763,-67.8751 51.763,-67.8751 51.763,-67.8751 48.178,-64.3897 48.6261,-71.1016 44.593,-60.9043 44.593,-60.9043"/> | |
</g> | |
<!-- SubF --> | |
<g id="PhysicalSystem/Functions/SubF" class="node"><title>SubF</title> | |
<polygon fill="#f0f8ff" stroke="black" points="126,-60.8 72,-60.8 72,-24.8 126,-24.8 126,-60.8"/> | |
<text text-anchor="middle" x="99" y="-38.6" font-family="Courier New" font-size="14.00">SubF</text> | |
</g> | |
<!-- Test->SubF --> | |
<g id="PhysicalSystem_edge2" class="edge"><title>Test->SubF</title> | |
<path fill="none" stroke="black" d="M99,-96.4966C99,-88.7827 99,-79.5125 99,-70.9124"/> | |
<polygon fill="black" stroke="black" points="99,-60.9043 103.5,-70.9043 99,-65.9043 99.0001,-70.9043 99.0001,-70.9043 99.0001,-70.9043 99,-65.9043 94.5001,-70.9044 99,-60.9043 99,-60.9043"/> | |
</g> | |
<!-- MulF --> | |
<g id="PhysicalSystem/Functions/MulF" class="node"><title>MulF</title> | |
<polygon fill="#f0f8ff" stroke="black" points="198,-60.8 144,-60.8 144,-24.8 198,-24.8 198,-60.8"/> | |
<text text-anchor="middle" x="171" y="-38.6" font-family="Courier New" font-size="14.00">MulF</text> | |
</g> | |
<!-- Test->MulF --> | |
<g id="PhysicalSystem_edge3" class="edge"><title>Test->MulF</title> | |
<path fill="none" stroke="black" d="M116.798,-96.4966C125.604,-87.935 136.382,-77.4562 146.001,-68.1045"/> | |
<polygon fill="black" stroke="black" points="153.407,-60.9043 149.374,-71.1016 149.822,-64.3897 146.237,-67.8751 146.237,-67.8751 146.237,-67.8751 149.822,-64.3897 143.1,-64.6487 153.407,-60.9043 153.407,-60.9043"/> | |
</g> | |
</g> | |
</svg> | |
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient> | |
</XholonWorkbook> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment