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

Feature request: Expose the task modifiers and modifier args on a `Task` object #433

Open lougreenwood opened 3 years ago

lougreenwood commented 3 years ago

I have an AsyncButton component which can be used to trigger single or parallel task performs on click.

Currently my API for controlling this requires knowledge of the task implementation to decide whether the button should be allowed to trigger additional tasks on click or disable the button when a single task is running:

<AsyncButton
  @allowConcurrency={{true}}
  @task={{this.someTask}}
/>

Ideally, I would like to remove the need for this allowConcurrency flag and instead derive this from the type of task or the modifiers, for example, if the button could check if it is a restartableTask, then the button would automatically disable concurrency, or if it were a standardTask with maxConcurrency = 2 and one task is only running, then allowConcurrency is true, but when the user clicks again, the AsyncButton component would detect hitting the allowConcurrency limit and then automatically disable additional concurrency until a task completes.

Ideally I suppose that the Task API would generically expose the type of modifier used and also any arguments passed to the modifier (include the default Task "modifier").

maxfierke commented 3 years ago

This dovetails nicely with the next RFC I'm working on, which is a public API for TaskFactory and opening up task modifiers for extension. All of this stuff already lives as private properties on tasks already, so I will play around with some notion of task metadata within that. Stay tuned!

lougreenwood commented 2 years ago

@maxfierke do you have a tracking issue for your RFC or anything similar that I can link to? 🙂

maxfierke commented 2 years ago

@maxfierke do you have a tracking issue for your RFC or anything similar that I can link to? 🙂

Not really 😬 just one of my many projects, but will try to get a write-up posted soon-ish

maxfierke commented 2 years ago

@lougreenwood sorry for the long wait, but I have an RFC posted in #441 that will provide some exposure to this data (I think there's still some work to be done on how to access this. Through the task might be fine, but I'm also thinking about a getTaskMetadata yieldable or something)

machty commented 2 years ago

This reminds me of something I semi-implemented back in 2016/2017 and might have even shipped undocumented in EC before removing it. I was basically trying to come up with really advanced use cases for Derived State, so that you could use properties of a task to answer the questions:

  1. If I .perform() this task, will the new TaskInstance start running immediately? (true for all restartable tasks, and true for other task types only if there is space for the new TaskInstance to run)
  2. If I .perform() this task, can/will the new TaskInstance start running without having any side effects on other TaskInstances (true for any task that has space in the queue for the new instance to run)

Maybe we could consider adding two more standard properties canPerform and canPerformSafe (open to wordsmithing) for these two respective questions?

maxfierke commented 2 years ago

@machty your comment gets at another RFC I have in the back of my brain, for public SchedulerPolicy and Scheduler APIs (which already exist, but making it possible to define them in application/addons is the missing piece). Was planning to tackle post-#441

could have those canPerform, canPerformSafe, etc. be a part of the SchedulerPolicy or something, and surface that through some Task metadata API

maxfierke commented 2 years ago

@lougreenwood unfortunately didn't quite get to exposing this info for the Task Modifiers RFC released in 2.2.0, as there were some dependencies on Scheduler stuff that needs some work to be made more visible, but that's the next piece of work I'm going to work on for a 2.3.0.