Detailed changes
@@ -5491,6 +5491,15 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "gpui_tokio"
+version = "0.1.0"
+dependencies = [
+ "gpui",
+ "tokio",
+ "util",
+]
+
[[package]]
name = "grid"
version = "0.13.0"
@@ -10746,6 +10755,7 @@ dependencies = [
"git",
"git_hosting_providers",
"gpui",
+ "gpui_tokio",
"http_client",
"language",
"language_extension",
@@ -16439,6 +16449,7 @@ dependencies = [
"git_ui",
"go_to_line",
"gpui",
+ "gpui_tokio",
"http_client",
"image_viewer",
"inline_completion_button",
@@ -2,7 +2,6 @@
resolver = "2"
members = [
"crates/activity_indicator",
- "crates/zed_predict_tos",
"crates/anthropic",
"crates/assets",
"crates/assistant",
@@ -31,8 +30,8 @@ members = [
"crates/context_server_settings",
"crates/copilot",
"crates/db",
- "crates/diagnostics",
"crates/deepseek",
+ "crates/diagnostics",
"crates/docs_preprocessor",
"crates/editor",
"crates/evals",
@@ -51,10 +50,12 @@ members = [
"crates/fuzzy",
"crates/git",
"crates/git_hosting_providers",
+ "crates/git_ui",
"crates/go_to_line",
"crates/google_ai",
"crates/gpui",
"crates/gpui_macros",
+ "crates/gpui_tokio",
"crates/html_to_markdown",
"crates/http_client",
"crates/image_viewer",
@@ -103,6 +104,7 @@ members = [
"crates/remote_server",
"crates/repl",
"crates/reqwest_client",
+ "crates/reqwest_client",
"crates/rich_text",
"crates/rope",
"crates/rpc",
@@ -141,7 +143,6 @@ members = [
"crates/ui",
"crates/ui_input",
"crates/ui_macros",
- "crates/reqwest_client",
"crates/util",
"crates/vcs_menu",
"crates/vim",
@@ -151,8 +152,8 @@ members = [
"crates/worktree",
"crates/zed",
"crates/zed_actions",
+ "crates/zed_predict_tos",
"crates/zeta",
- "crates/git_ui",
#
# Extensions
@@ -253,6 +254,7 @@ gpui = { path = "crates/gpui", default-features = false, features = [
"http_client",
] }
gpui_macros = { path = "crates/gpui_macros" }
+gpui_tokio = { path = "crates/gpui_tokio" }
html_to_markdown = { path = "crates/html_to_markdown" }
http_client = { path = "crates/http_client" }
image_viewer = { path = "crates/image_viewer" }
@@ -0,0 +1,18 @@
+[package]
+name = "gpui_tokio"
+version = "0.1.0"
+edition.workspace = true
+publish.workspace = true
+license = "Apache-2.0"
+
+[lints]
+workspace = true
+
+[lib]
+path = "src/gpui_tokio.rs"
+doctest = false
+
+[dependencies]
+util.workspace = true
+gpui.workspace = true
+tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
@@ -0,0 +1 @@
+../../LICENSE-APACHE
@@ -0,0 +1,55 @@
+use std::future::Future;
+
+use gpui::{App, Global, ReadGlobal, Task};
+use tokio::task::JoinError;
+use util::defer;
+
+pub fn init(cx: &mut App) {
+ cx.set_global(GlobalTokio::new());
+}
+
+struct GlobalTokio {
+ runtime: tokio::runtime::Runtime,
+}
+
+impl Global for GlobalTokio {}
+
+impl GlobalTokio {
+ fn new() -> Self {
+ let runtime = tokio::runtime::Builder::new_multi_thread()
+ // Since we now have two executors, let's try to keep our footprint small
+ .worker_threads(2)
+ .enable_all()
+ .build()
+ .expect("Failed to initialize Tokio");
+
+ Self { runtime }
+ }
+}
+
+pub struct Tokio {}
+
+impl Tokio {
+ /// Spawns the given future on Tokio's thread pool, and returns it via a GPUI task
+ /// Note that the Tokio task will be cancelled if the GPUI task is dropped
+ pub fn spawn<Fut, R>(cx: &mut App, f: Fut) -> Task<Result<R, JoinError>>
+ where
+ Fut: Future<Output = R> + Send + 'static,
+ R: Send + 'static,
+ {
+ let join_handle = GlobalTokio::global(cx).runtime.spawn(f);
+ let abort_handle = join_handle.abort_handle();
+ let cancel = defer(move || {
+ abort_handle.abort();
+ });
+ cx.background_executor().spawn(async move {
+ let result = join_handle.await;
+ drop(cancel);
+ result
+ })
+ }
+
+ pub fn handle(cx: &mut App) -> tokio::runtime::Handle {
+ GlobalTokio::global(cx).runtime.handle().clone()
+ }
+}
@@ -36,6 +36,7 @@ futures.workspace = true
git.workspace = true
git_hosting_providers.workspace = true
gpui.workspace = true
+gpui_tokio.workspace = true
http_client.workspace = true
language.workspace = true
language_extension.workspace = true
@@ -9,6 +9,7 @@ use futures::channel::mpsc;
use futures::{select, select_biased, AsyncRead, AsyncWrite, AsyncWriteExt, FutureExt, SinkExt};
use git::GitHostingProviderRegistry;
use gpui::{App, AppContext as _, Context, Entity, SemanticVersion, UpdateGlobal as _};
+use gpui_tokio::Tokio;
use http_client::{read_proxy_from_env, Uri};
use language::LanguageRegistry;
use node_runtime::{NodeBinaryOptions, NodeRuntime};
@@ -425,6 +426,7 @@ pub fn execute_run(
settings::init(cx);
let app_version = AppVersion::init(env!("ZED_PKG_VERSION"));
release_channel::init(app_version, cx);
+ gpui_tokio::init(cx);
HeadlessProject::init(cx);
@@ -445,18 +447,21 @@ pub fn execute_run(
let proxy_url = read_proxy_settings(cx);
- let http_client = Arc::new(
- ReqwestClient::proxy_and_user_agent(
- proxy_url,
- &format!(
- "Zed-Server/{} ({}; {})",
- env!("CARGO_PKG_VERSION"),
- std::env::consts::OS,
- std::env::consts::ARCH
- ),
+ let http_client = {
+ let _guard = Tokio::handle(cx).enter();
+ Arc::new(
+ ReqwestClient::proxy_and_user_agent(
+ proxy_url,
+ &format!(
+ "Zed-Server/{} ({}; {})",
+ env!("CARGO_PKG_VERSION"),
+ std::env::consts::OS,
+ std::env::consts::ARCH
+ ),
+ )
+ .expect("Could not start HTTP client"),
)
- .expect("Could not start HTTP client"),
- );
+ };
let node_runtime = NodeRuntime::new(http_client.clone(), node_settings_rx);
@@ -59,6 +59,7 @@ git_ui.workspace = true
git_hosting_providers.workspace = true
go_to_line.workspace = true
gpui = { workspace = true, features = ["wayland", "x11", "font-kit"] }
+gpui_tokio.workspace = true
http_client.workspace = true
image_viewer.workspace = true
inline_completion_button.workspace = true
@@ -20,6 +20,7 @@ use futures::{future, StreamExt};
use git::GitHostingProviderRegistry;
use gpui::{App, AppContext as _, Application, AsyncApp, UpdateGlobal as _};
+use gpui_tokio::Tokio;
use http_client::{read_proxy_from_env, Uri};
use language::LanguageRegistry;
use log::LevelFilter;
@@ -279,6 +280,7 @@ fn main() {
app.run(move |cx| {
release_channel::init(app_version, cx);
+ gpui_tokio::init(cx);
if let Some(build_sha) = option_env!("ZED_COMMIT_SHA") {
AppCommitSha::set_global(AppCommitSha(build_sha.into()), cx);
}
@@ -302,8 +304,11 @@ fn main() {
.ok()
})
.or_else(read_proxy_from_env);
- let http = ReqwestClient::proxy_and_user_agent(proxy_url, &user_agent)
- .expect("could not start HTTP client");
+ let http = {
+ let _guard = Tokio::handle(cx).enter();
+ ReqwestClient::proxy_and_user_agent(proxy_url, &user_agent)
+ .expect("could not start HTTP client")
+ };
cx.set_http_client(Arc::new(http));
<dyn Fs>::set_global(fs.clone(), cx);