machty / ember-concurrency

ember-concurrency is an Ember Addon that enables you to write concise, worry-free, cancelable, restartable, asynchronous tasks.
http://ember-concurrency.com
MIT License
691 stars 155 forks source link

Migration guide for task groups #482

Open nwhittaker opened 1 year ago

nwhittaker commented 1 year ago

With task groups deprecated in 2.3.0, is there a recommended way for migrating code that was previously relying on group functionality?

machty commented 1 year ago

Agree that we should flesh this out more. @sukima wrote the following code snippet that could be used to replace task groups:

class Component {
  group = task({ drop: true }, async (taskName) => {
    switch (taskName) {
      case 'taskA': return await this.#taskA.perform();
      case 'taskB': return await this.#taskB.perform();
      default: throw new ReferenceError(`Unknown task '${taskName}'`);
    }
  });
  #taskA = task(…);
  #taskB = task(…);
}

After some discussion it might make sense to gently reintroduce Task Groups, but my feeling lately is that it is a bit of an "over-solve" that is too specific to Tasks, and it's very easy to abuse them or have them almost-but-not-quite-work, because the general primitive you want is more like an actor model or state machine with more top-level control of what tasks can run at the same time. Task Groups are kinda like that, but the way the tasks "late-bind" to their task group is among one of the messier 2016-era aspects of the EC API i'm trying to get away from, and my attempts to "fix" this API always end up with something that just looks eerily similar to xstate and ember-statecharts, so I'm more interested in exploring composable patterns with that ecosystem than to maintain EC's particular flavor of task coordination.

nwhittaker commented 1 year ago

Thanks for the snippet and the explanation -- much appreciated. One follow-on concern w/ this example is with passing different sets of arguments to each child task and if it can be done in a way that works well with TypeScript?

sukima commented 1 year ago

Thanks for the snippet and the explanation -- much appreciated. One follow-on concern w/ this example is with passing different sets of arguments to each child task and if it can be done in a way that works well with TypeScript?

I'm sure there is a fancy way to do that. Though at that point you might consider making your own class that manages the complexity of dispatching (performing) tasks. Like @machty mentioned, this is an area where statecharts excel at.