<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]--></head><body><div style="color:#000; background-color:#fff; font-family:HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:16px"><div id="yui_3_16_0_ym19_1_1474984041665_688120" dir="ltr"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688227">> I'd rather see this implemented by seeing one track the timers they use </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688228"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688229">> (with their Refs), and their action from the message is dependent on </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688230"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688231">> their state (halted or auto_attacking). What you're advocating is doing </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688232"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688233">> that tracking by hand based on some other unrelated state, and you're </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688234"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688235">> actively fighting one of the states that could exist in your FSM!</span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688236"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688250">> </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688237"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688238">> At the very least, that sounds better than adding yet more features into </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688239"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688240">> the gen_statem behaviour, which is gathering requirements at a fairly </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688241"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_688242">> rapid rate so far.<br></span><br>A NFA <a href="https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton" class="enhancr2_41f00706-3253-e3dc-9942-fe83f04b49c2" id="yui_3_16_0_ym19_1_1474984041665_688352">Nondeterministic finite automaton - Wikipedia, the free encyclopedia</a> by definition is a state machine that can be in multiple states simultaneously.<br><br>Do we really need a gen_statem_nfa module now?<br><br>From a basic use case of a connection that needs to send keep alives at regular intervals. This "unnecessary feature" is screaming include me.<br>To be clear the connection has 2 timers, timer 1 is if there has not been a message received in x amount of time. Timer 2 is the "when to send keep alive" timer.<br><br>If a packet arrives on the connection, we bump the keep-alive timer since we know the peer is alive. This is a pretty basic feature.<br>And being able to bump the keep-alive time this way will require keeping timer refs and using cancel_timer + purging mailbox.<br><br>Its the natural way you want to write the gen_statem behavior. At least IMO.<br><br><br><br>This single state way does not work, it works in simple use cases like a safe/lock or basic phone call. But it<br>does not work in more complex applications.<br><br>The individual states could be running, jumping and attacking. Do you really want to write a combo state for each occurrence?<br><br>moving, attacking, jumping, stopped, moving_attacking, moving_attacking_jumping, attacking_jumping, moving_jumping, jumping_stopped, .. etc<br><br>From what your saying, the state machine needs to be in ONLY ONE of these states at a time.<br><br><br></div><div id="yui_3_16_0_ym19_1_1474984041665_688120" dir="ltr"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_692792">> This is a state machine behaviour! If you're buffed, this should be </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_692793"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_692794">> represented in your state explicitly rather than implicitly within the </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_692795"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_692796">> state machine mechanisms!<br></span><br></div><div id="yui_3_16_0_ym19_1_1474984041665_688120" dir="ltr">This is true. But then there needs to be a way to get the timer ref. Sometimes Erlangs approach is, just make it work. <br>I don't see any way to get the timer ref without including it in the callback OR creating your own timer and including it for tracking (vs just specifying the timeout).<br><br><br><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_695024">> Think for example that you upgrade a node's code. One thing to consider </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_695025"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_695026">> is that after the upgrade you may add or remove timers. <br></span><br>I did not consider this. This is truly problematic BUT would not the current way timeout works run into this same problem?</div><div id="yui_3_16_0_ym19_1_1474984041665_688120" dir="ltr"> So this should not affect allowing multiple timeouts vs a single timeout.<br><br><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_694953"> > Hell, you could even start a related </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_694954"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_694955">> 'timeout' FSM that sends message at specific intervals to your own FSM </span><br clear="none" style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_694956"><span style="font-family: "Helvetica Neue", "Segoe UI", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 13px;" id="yui_3_16_0_ym19_1_1474984041665_694957">> and manage that one<br></span><br>I tried this way before and it was not very performant. Sending a timeout every 100ms and managing tons of other timers in that timeout<br>was very poor performance. The reason is I needed acceptable latency and did not want to deal with cancel_timer. Changing to gen_statem </div><div id="yui_3_16_0_ym19_1_1474984041665_688120" dir="ltr">timeout dropped the 16 phys core (with 200k erlang processes) cpu usage from 50% to 0-1%.<br><br>Learning from that, I rather this be inside gen_statem. If its not, I would have no problem to write my own little timer library for cancel_timer+purging mailbox. <br><br><br><br>Either way to me having 1 timeout that can proc a UNIQUE EventContent is silly. It should be fixed then. A timeout ONLY procs a timeout event, this way<br>you wont accidentally override the timeout EventContent.<br><br>Since you are only in ONE state at a time, you automatically know if the timeout happened, it MUST correspond to the current state we are in. <br><br>Another option is to remove the timeout then. It just seems out of place to me. <br><br>What is the use case of a single timeout with a UNIQUE EventContent? <br><br>Its not to allow the gen_statem to tick itself, (which gen_event lacked) if it was there would not be a way to pass a unique EventContent.<br><br>Unique event content is misleading making you think if you pass a different EventContent, it will NOT override a previous EventContent.<br><br></div> <div class="qtdSeparateBR" id="yui_3_16_0_ym19_1_1474984041665_688158"><br><br></div><div class="yahoo_quoted" style="display: block;" id="yui_3_16_0_ym19_1_1474984041665_688157"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;" id="yui_3_16_0_ym19_1_1474984041665_688156"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;" id="yui_3_16_0_ym19_1_1474984041665_688155"> <div dir="ltr" id="yui_3_16_0_ym19_1_1474984041665_688164"><font size="2" face="Arial" id="yui_3_16_0_ym19_1_1474984041665_688163"> On Tuesday, October 4, 2016 3:39 PM, Fred Hebert <mononcqc@ferd.ca> wrote:<br></font></div> <br><br> <div class="y_msg_container" id="yui_3_16_0_ym19_1_1474984041665_688154">On 10/04, Vans S wrote:<br clear="none">>Picture a game where you autoattack every 1000ms, if you use Halt <br clear="none">>command your autoattack stops and movement stops.<br clear="none">>The return will look like [{named_timeout, infinity, <br clear="none">>auto_attack}, {named_timeout, infinity, move}]. In this case if we <br clear="none">>were not autoattacking butmoving and halted we would crash. Which is <br clear="none">>bad. It adds unneeded complexity.<br clear="none">><br clear="none"><br clear="none">I'd rather see this implemented by seeing one track the timers they use <br clear="none">(with their Refs), and their action from the message is dependent on <br clear="none">their state (halted or auto_attacking). What you're advocating is doing <br clear="none">that tracking by hand based on some other unrelated state, and you're <br clear="none">actively fighting one of the states that could exist in your FSM!<br clear="none"><br clear="none">At the very least, that sounds better than adding yet more features into <br clear="none">the gen_statem behaviour, which is gathering requirements at a fairly <br clear="none">rapid rate so far.<br clear="none"><br clear="none">><br clear="none">>For example, if we have a moral boost buff that lasts 10,000ms, and we receive another 10,000ms moral boost buff that stacks, we want to increment <br clear="none">>the current 10,000ms moral_buff timeout by 10,000ms more. Maybe on named_timeout callback pass the list of all Timers registered, or at least [{Name, TimeRemaining}] ?<br clear="none">><br clear="none"><br clear="none">This is a state machine behaviour! If you're buffed, this should be <br clear="none">represented in your state explicitly rather than implicitly within the <br clear="none">state machine mechanisms!<br clear="none"><br clear="none">Think for example that you upgrade a node's code. One thing to consider <br clear="none">is that after the upgrade you may add or remove timers. However, the <br clear="none">code change mechanism does not allow you to manage that kind of stuff: <br clear="none">you can only modify your own state and data, but not play with the event <div class="yqt2755463648" id="yqtfd47172"><br clear="none">mailbox.</div><br clear="none"><br clear="none">To be able to change your logic around timeouts during a pause would <br clear="none">require you to move them to your own FSM's data and to ignore old <br clear="none">references, no way around it.<br clear="none"><br clear="none">There's a benefit to handling that kind of stuff explicitly, and if <br clear="none">timers are integral to your system progressing, you should probably take <br clear="none">a more direct approach to it. Hell, you could even start a related <br clear="none">'timeout' FSM that sends message at specific intervals to your own FSM <br clear="none">and manage that one, rather than doing it all through the more <br clear="none">restrictive interface.<div class="yqt2755463648" id="yqtfd70481"><br clear="none"><br clear="none"></div><br><br></div> </div> </div> </div></div></body></html>