Skip to content

Assertion when implementing “join running task instance” pattern (task.isRunning + perform) in ember-concurrency 5 / Ember 6 #606

Description

@AmilKey

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions