Every Ember object has an implicit looping process that looks like:

    main: process(function * () {
      for (;;) {
        let args = yield waitForAction();

        // args === ['cancelForm', 1, 2, 3]
        let actionName = args.shift();
        this.actions[actionName].apply(this, args);
      }
    }),

This does nothing other than repeatedly wait for one of the actions
in the actions hash to be fired from a template. By default, there
is no blocking that occurs while an action is behind handled; it
just runs the action function and synchronously completes, disregarding
its return value, and continues onward. There's no coordination
between actions whatsoever; any coordination that occurs must be
done through manual management of state.

    actions: {
      cancelForm() {
        // do side-effecty thing that should prevent the other
      },

      submitForm() {
        // do side-effecty thing that should prevent the other
      },
    }

To get this right, you have to set "isIdle" to false/true, or some other
state, and then remember to unset it afterward.

What if action's "knew" whether they were invocable or not?
What if you could write the following in your templates:

    {{action-button "Cancel Form" (action 'cancelForm')}}
    {{action-button "Submit Form" (action 'submitForm')}}

Assume `action-button` is a component that presents a button, whose
display / clickable state depends on the state of the action object
passed in. What we want is to tell the system just enough for it
to figure these things out on its own. Maybe our looper can play a role
here. What if our looper looked like this:

    main: process(function * () {
      for (;;) {
        let args = yield waitForAction();

        // args === ['cancelForm', 1, 2, 3]
        let actionName = args.shift();
        this.actions[actionName].apply(this, args);

        yield sleep(1000);
      }
    }),

You could either write:

    mainLoop: function * () {
      for (;;) {
        let args = yield waitForAction();

        // args === ['cancelForm', 1, 2, 3]
        let actionName = args.shift();
        this.actions[actionName].apply(this, args);

        yield sleep(1000);
      }
    },

or just

    mainLoop: function * () {
      let args = yield waitForAction();

      // args === ['cancelForm', 1, 2, 3]
      let actionName = args.shift();
      this.actions[actionName].apply(this, args);

      yield sleep(1000);
    },

ember-processes is smart enough to know if you yielded anything.
If you did, then loop... is that stupid? That might be stupid.
Maybe do this:

    mainLoop: function * () {
      let args = yield waitForAction();

      // args === ['cancelForm', 1, 2, 3]
      let actionName = args.shift();
      this.actions[actionName].apply(this, args);

      yield sleep(1000);
      yield restart();
    },

Anyway, Channels: they are already established as extremely powerful by
Golang and core.async in Clojure. In Ember we could expose their blocked
state, of which there are three:

- consumer is blocked
  - e.g. a Component is waiting for an action to fire, which it can
    handle right away
- producer is blocked
  - e.g. a Component either isn't waiting for that particular action to
    fire, or is busy handling a previously fired action
  - question: should we distinguish b/w the above?
- no one is blocked
  - what does this even mean? it means there's a channel with no
    producers or consumers. It means... the absence of an action?

It is impossible for both consumer and producer to be blocked.

So how do we think about actions? One of two ways:

- each action has its own channel
- all actions by default fire on the same channel

In both cases we have to answer this: how to we opt in/out of
blocking until the action is completed? Side question: is there
ever a time when you want 2 3 4 but not 5 simultaneous runs
of a function? Or is it always one at a time, or unbounded?

In fact, if we assume that everything in the `actions` hash
is "live", then there's no difference. It just means we can
avoid a select invocation. By default we "select" all actions
in the actions hash, hence they are all live.

But this gives us some stuff to explore:

#### Example: wait 1 sec between actions:

    main: process(function * () {
      for (;;) {
        let args = yield waitForAction();

        // args === ['cancelForm', 1, 2, 3]
        let actionName = args.shift();
        this.actions[actionName].apply(this, args);

        yield sleep(1000);
      }
    }),

This example still disregards the return value of the action handlers,
but due to the `sleep(1000)`, all those `{{action}}`s in the template
while be blocked by the consumer, and hence inactive. Now, we ALSO
know which action caused that blockage. Whichever one was selected
can be displayed as active, until...?

Well at least until it's ready to be clicked again. So if you have
these buttons

    [  ] [  ] [  ] [  ]

and they each point to an action and you tap the third one, you get

    [  ] [  ] [XX] [  ]

for 1 second until it loops back around to the waitForAction and then
you're back to

    [  ] [  ] [  ] [  ]

If you want to have that button stick around, then you need to do some
other form of state management. Maybe there's a way to design the code
to ignore all buttons except the "active" one? I dunno.

#### Musings:

To autoStart or not to autoStart...

    // so question: it seems nice to autostart on everything,
    // but what happens if one of the channels closes?
    // how do you restart a process blocked on a channel
    // that's now closed?
    //
    // Question: when would a channel ever close for a CP
    // process? Maybe all the time? If you're branching on actions
    // and one of the actions gets unrendered? i Dunno.


Unrelated:

Channels could have process constructors? They're yieldable
but they also just publish? I dunno. Use case is: if you're
making a process just so it can yield values into a channel,
maybe it'd be better to consolidate? Then you could remove the
.puts method from the other side of it. Seems nice?

    /*
    activityChannel: channel(function * (publish) {
      for (;;) {
        publish(123);
      }
      //for (;;) {
        //yield timeout(500);
        //yield chan.put(123);
      //}
    }),
    */

    //activityChannel: channel(Observable.interval(500)),
    /*
    activityChannel: channel(function(publish)  {
      publish(1);
      publish(2);
      publish(3);
      publish(4);
      publish.close();

      return () => {
        // teardown
      };
    }),
    */

what

    let action = yield gimmeAnAction;

    // [ doThing 'a' ] [ doThing 'b' ] [ doThing 'c' ]
    // only one of these can fire. you wanna be able to
    // signal to the others why they're blocked.

    action.set('status', 'busy')


so if you yield an action, you get a mutable object you can fuck with.
it represents an ActionInvocation.

    let invocation = yield waitForActions("WAT_WAT_WAT")
    deepEqual(invocation, {
      type: "BLORG_ASSHOLE",
      payload: {},
    })

Or the mapping fn can just create a new one..........
channelAction.



yield 




