This is a proposal to deprecate the Tokio LocalSet abstraction in favor of a new LocalRuntime type. Currently, to spawn !Send tasks on Tokio you must use a combination of a current-thread runtime and LocalSet to make that work. However, tasks on a LocalSet are separate from the rest of the runtime in an uncomfortable way. For example:
- Tasks on the
LocalSet can tokio::spawn to get onto the runtime, but once you're on the runtime, you can no longer spawn_local to get back into the LocalSet.
- From the runtime's perspective, all of the tasks in the
LocalSet behave like a single task using FuturesUnordered, so various runtime options such as event_interval behave in a very surprising way by counting many tasks as a single task.
- After discussions with Deno (a while ago), use of
LocalSet has been shown to involve considerable performance overhead compared to unsafely spawning the !Send tasks onto a current-thread runtime.
Because of the above, I have proposed to add a new type called LocalRuntime which will be the replacement. Please see #6739 for the feature request to add that type. However, beyond just adding a new LocalRuntime type, I am also proposing to formally deprecate the LocalSet type. That's this issue.
Specifically, I am proposing the following course of action:
- First, we add a
LocalRuntime type, which would close #6739.
- Then, 6 months later, we add
#[deprecated] to the LocalSet type, so that existing users of LocalSet receive a warning that recommends LocalRuntime.
- Finally, since we are a stable 1.x crate, we keep
LocalSet working forever.
I believe that all existing uses of LocalSet can be replaced either by the new LocalRuntime or by FuturesUnordered. The advantage of this approach is that the current design of LocalSet make it impossible to add some features without having them be really confusing:
- Issue #3181 proposes to add hooks that run when a task is spawned / destroyed. The hooks would not run for tasks on the
LocalSet. This is confusing.
- Task dumps currently don't look inside
block_on, which means that LocalSet tasks are completely invisible to task dumps.
In both cases, supporting LocalSet well is very difficult. As long as LocalSet remains a first-class citizen, it is difficult to introduce new features that affect all tasks without having confusing behavior when LocalSet is used.
Note that spawn_local is not being deprecated. The intent is that it will work together with LocalRuntime.
Some alternative options:
- Do nothing. The previously mentioned disadvantages apply.
- Add
LocalRuntime but do not deprecate LocalSet. This provides a way to work around the performance issues of LocalSet, but ultimately it is still difficult to introduce new features that affect all tasks on the runtime.
The purpose of this issue is to gather feedback from users of LocalSet. Please post your experience below. I am especially interested in use-cases that cannot be replaced by LocalRuntime or FuturesUnordered.
This is a proposal to deprecate the Tokio
LocalSetabstraction in favor of a newLocalRuntimetype. Currently, to spawn!Sendtasks on Tokio you must use a combination of a current-thread runtime andLocalSetto make that work. However, tasks on aLocalSetare separate from the rest of the runtime in an uncomfortable way. For example:LocalSetcantokio::spawnto get onto the runtime, but once you're on the runtime, you can no longerspawn_localto get back into theLocalSet.LocalSetbehave like a single task usingFuturesUnordered, so various runtime options such asevent_intervalbehave in a very surprising way by counting many tasks as a single task.LocalSethas been shown to involve considerable performance overhead compared to unsafely spawning the!Sendtasks onto a current-thread runtime.Because of the above, I have proposed to add a new type called
LocalRuntimewhich will be the replacement. Please see #6739 for the feature request to add that type. However, beyond just adding a newLocalRuntimetype, I am also proposing to formally deprecate theLocalSettype. That's this issue.Specifically, I am proposing the following course of action:
LocalRuntimetype, which would close #6739.#[deprecated]to theLocalSettype, so that existing users ofLocalSetreceive a warning that recommendsLocalRuntime.LocalSetworking forever.I believe that all existing uses of
LocalSetcan be replaced either by the newLocalRuntimeor byFuturesUnordered. The advantage of this approach is that the current design ofLocalSetmake it impossible to add some features without having them be really confusing:LocalSet. This is confusing.block_on, which means thatLocalSettasks are completely invisible to task dumps.In both cases, supporting
LocalSetwell is very difficult. As long asLocalSetremains a first-class citizen, it is difficult to introduce new features that affect all tasks without having confusing behavior whenLocalSetis used.Note that
spawn_localis not being deprecated. The intent is that it will work together withLocalRuntime.Some alternative options:
LocalRuntimebut do not deprecateLocalSet. This provides a way to work around the performance issues ofLocalSet, but ultimately it is still difficult to introduce new features that affect all tasks on the runtime.The purpose of this issue is to gather feedback from users of
LocalSet. Please post your experience below. I am especially interested in use-cases that cannot be replaced byLocalRuntimeorFuturesUnordered.