Title
Assertion when implementing “join running task instance” pattern (task.isRunning + perform) in ember-concurrency 5 / Ember 6
Description
After upgrading to ember-concurrency v5 (and Ember 6 / autotracking), a common pattern “don’t start task again; if already running, wait for the current instance and reuse its result” now throws an autotracking assertion.
Old code (worked in previous versions):
if (this.doc.blob.isRunning) {
yield waitForProperty(this.doc, 'blob.isIdle');
blob = this.doc.blob.last.value;
} else {
blob = yield this.doc.blob.perform(true);
}
Now it fails with:
Error: Assertion Failed:
You attempted to update `isRunning` on `<Task:blob>`,
but it had already been used previously in the same computation.
Attempting to update a value after using it in a computation can cause
logical errors, infinite revalidation bugs, and performance issues, and is not supported.
This seems to be the same class of issue as older reports about updating derived state (numRunning / isRunning) after reading it in the same computation (#378), but it is still reproducible in EC6 with modern Ember autotracking. ([GitHub][1])
Expected behavior
A safe/idiomatic way to “join” a running task instance should be possible without needing to manually break autotracking computations.
Specifically:
- If
blob is running, do not start a new instance.
- Wait for the current one and return its
value.
Actual behavior
Reading task.isRunning and then calling task.perform() in the same synchronous tick triggers Ember’s autotracking assertion.
This effectively breaks the previous “join existing instance” pattern and pushes users to add artificial async boundaries.
Questions / proposal
- Is there a recommended idiomatic pattern for “join existing task instance” in EC6 that doesn’t require manual async boundaries or caching boilerplate?
- Could ember-concurrency provide a helper / API for this use case (e.g.
task.join(), task.performUnlessRunning(), or similar), or adjust derived state tagging to make the old pattern safe?
Versions
- ember-concurrency: 5.x
- ember-source: 6.x
Title
Assertion when implementing “join running task instance” pattern (
task.isRunning+perform) in ember-concurrency 5 / Ember 6Description
After upgrading to ember-concurrency v5 (and Ember 6 / autotracking), a common pattern “don’t start task again; if already running, wait for the current instance and reuse its result” now throws an autotracking assertion.
Old code (worked in previous versions):
Now it fails with:
This seems to be the same class of issue as older reports about updating derived state (
numRunning/isRunning) after reading it in the same computation (#378), but it is still reproducible in EC6 with modern Ember autotracking. ([GitHub][1])Expected behavior
A safe/idiomatic way to “join” a running task instance should be possible without needing to manually break autotracking computations.
Specifically:
blobis running, do not start a new instance.value.Actual behavior
Reading
task.isRunningand then callingtask.perform()in the same synchronous tick triggers Ember’s autotracking assertion.This effectively breaks the previous “join existing instance” pattern and pushes users to add artificial async boundaries.
Questions / proposal
task.join(),task.performUnlessRunning(), or similar), or adjust derived state tagging to make the old pattern safe?Versions