• Hans Fugal's avatar
    wangle::detail::FSM · 8e1a61fa
    Hans Fugal authored
    Summary:
    spaghetti-monster
    
    Finagle uses a nifty state machine pattern in `Promise.scala`. Each state carries its data with it, then you switch statements with a simple state `cas`, within the functions (which are the transition inputs). See https://github.com/twitter/util/blob/master/util-core/src/main/scala/com/twitter/util/Promise.scala#L133-L139 and https://github.com/twitter/util/blob/master/util-core/src/main/scala/com/twitter/util/Promise.scala#L604-L635 for example.
    
    I was thinking we could do something similar in C++, though we don't quite have the same luxury of type cases like scala. (Although as an aside I found this really cool paper on implementing type cases in C++, it's kind of evil but very cool. http://www.stroustrup.com/OOPSLA-typeswitch-draft.pdf)
    
    I was looking at having a union of the different state classes, e.g.
    
    union U {
    State base;
    Done done;
    Waiting waiting;
    ...
    };
    
    and then you could use the memoized `dynamic_cast` trick in that paper to make a fairly efficient type case (and fairly readable, depending on how evil you want to get with the macros). However, `dynamic_cast<Done*>(&u.base)` blissfully segfaults. I'm not sure if this is something that should work and it's a compiler bug, or whether trying to (ab)use a union this way is against some arcane C++ rules. @hannesr suggested maybe a variant type might work. We can also do memory mangling on our own if it comes to it - however those are all more advanced techniques to play with at a later optimization time.
    
    So instead, I went for a this-is-context helper base class. The mutable context is just `this`, and you inherit from `FSM`.
    
    The magic macros make it more succint to lay out state transitions. See the tests for examples. Maybe in the future we can get really clever and find a way to generate state machine diagrams from code using this, especially when macros are being used.
    
    Test Plan: unit tests were written and pass
    
    Reviewed By: davejwatson@fb.com
    
    Subscribers: meisner, trunkagent, net-systems@, fugalh, exa, njormrod, hannesr
    
    FB internal diff: D1613497
    8e1a61fa
FSM.cpp 2.41 KB