# Concurrency and tasks

> The foreground thread, background work, and how tasks are kept alive.

GPUI has one foreground thread. All entity access and all rendering happen
there. Background threads do work that touches no entity.

```rust
// Foreground: may touch entities through the AsyncApp it receives.
cx.spawn(async move |this: WeakEntity<Self>, cx: &mut AsyncApp| {
    let result = cx.background_spawn(async move { expensive() }).await;
    this.update(cx, |this, cx| {
        this.result = Some(result);
        cx.notify();
    })
})
.detach();
```

Both `spawn` and `background_spawn` return a `Task<R>`. Dropping a task
cancels it, so every task must be awaited, detached
(`.detach()` or `.detach_and_log_err(cx)`), or stored in a field for as long
as the work should run.

Two conventions from Zed that this fork keeps:

- Scope clones with shadowing inside the spawn block:

  ```rust
  executor.spawn({
      let task_ran = task_ran.clone();
      async move { *task_ran.borrow_mut() = true; }
  });
  ```

- In tests, use the executor's timers
  (`cx.background_executor().timer(duration).await`) rather than `smol`
  timers, so `run_until_parked()` can drive them.
