Skip to content

Commit 71de70b

Browse files
authored
Wasm threading (#2517)
* Add threading on the Web Use the `wasm_thread` library to enable real `spawn_blocking` on the Web in `linera_base::task`.
1 parent 6be86a9 commit 71de70b

File tree

9 files changed

+30
-19
lines changed

9 files changed

+30
-19
lines changed

Cargo.lock

+13-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ wasm-bindgen-futures = "0.4.42"
159159
wasm-bindgen-test = "0.3.42"
160160
wasm-encoder = "0.24.1"
161161
wasm-instrument = "0.4.0"
162+
wasm_thread = "0.3.0"
162163
wasmer = { package = "linera-wasmer", version = "4.3.6-linera.3", default-features = false }
163164
wasmer-compiler-singlepass = { package = "linera-wasmer-compiler-singlepass", version = "4.3.6-linera.3" }
164165
wasmparser = "0.101.1"

examples/Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-base/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ web = [
2323
"tracing-web",
2424
"wasmtimer",
2525
"wasm-bindgen-futures",
26+
"wasm_thread",
2627
"web-time",
2728
]
2829

@@ -57,6 +58,7 @@ tokio = { workspace = true, features = ["time"] }
5758
tracing.workspace = true
5859
tracing-subscriber = { workspace = true, features = ["json", "fmt", "ansi"] }
5960
wasm-bindgen-futures = { workspace = true, optional = true }
61+
wasm_thread = { workspace = true, optional = true }
6062
wasmtimer = { workspace = true, optional = true }
6163
web-time = { workspace = true, optional = true }
6264

linera-base/src/task.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ mod implementation {
4646
/// The type of a future awaiting another thread.
4747
pub type BlockingFuture<R> = oneshot::Receiver<R>;
4848

49-
/// Spawns a new task, potentially on the current thread.
49+
/// Spawns a new task on the current thread.
5050
pub fn spawn<F: Future + 'static>(future: F) -> NonblockingFuture<F::Output> {
5151
let (send, recv) = oneshot::channel();
5252
wasm_bindgen_futures::spawn_local(async {
@@ -55,12 +55,15 @@ mod implementation {
5555
recv
5656
}
5757

58-
/// Spawns a blocking task on the same thread (!).
59-
/// TODO(#2399): replace this by a Web worker.
58+
/// Spawns a blocking task on a new Web Worker.
6059
pub fn spawn_blocking<R: Send + 'static, F: FnOnce() -> R + Send + 'static>(
6160
task: F,
6261
) -> BlockingFuture<R> {
63-
spawn(async { task() })
62+
let (send, recv) = oneshot::channel();
63+
wasm_thread::spawn(move || {
64+
let _ = send.send(task());
65+
});
66+
recv
6467
}
6568
}
6669

linera-execution/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ wasmer = { workspace = true, optional = true, features = ["sys-default", "single
6868

6969
[target.'cfg(target_arch = "wasm32")'.dependencies]
7070
tokio = { workspace = true, features = ["rt"] }
71-
wasmer = { workspace = true, optional = true, features = ["js-default"] }
71+
wasmer = { workspace = true, optional = true, features = ["js-default", "js-serializable-module"] }
7272

7373
[dev-dependencies]
7474
anyhow.workspace = true

linera-storage/Cargo.toml

+1-8
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,7 @@ repository.workspace = true
1212
version.workspace = true
1313

1414
[features]
15-
test = [
16-
"tokio/rt",
17-
"tokio/test-util",
18-
"tokio/time",
19-
"linera-execution/test",
20-
"linera-views/test",
21-
]
15+
test = ["linera-execution/test", "linera-views/test"]
2216
wasmer = ["linera-execution/wasmer"]
2317
wasmtime = ["linera-execution/wasmtime"]
2418
metrics = [
@@ -45,7 +39,6 @@ linera-execution.workspace = true
4539
linera-views.workspace = true
4640
prometheus.workspace = true
4741
serde.workspace = true
48-
tokio = { workspace = true, features = ["macros"] }
4942

5043
[dev-dependencies]
5144
anyhow.workspace = true

linera-storage/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn main() {
55
cfg_aliases::cfg_aliases! {
66
with_testing: { any(test, feature = "test") },
77
with_metrics: { all(not(target_arch = "wasm32"), feature = "metrics") },
8-
with_wasmer: { all(not(target_arch = "wasm32"), feature = "wasmer") },
8+
with_wasmer: { all(any(feature = "web", not(target_arch = "wasm32")), feature = "wasmer") },
99
with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") },
1010
with_wasm_runtime: { any(with_wasmer, with_wasmtime) },
1111
};

linera-storage/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ pub trait Storage: Sized {
193193
let mut tasks = Vec::new();
194194
for key in keys {
195195
let client = self.clone();
196-
tasks.push(tokio::task::spawn(async move {
196+
tasks.push(linera_base::task::spawn(async move {
197197
client.read_certificate(key).await
198198
}));
199199
}
@@ -295,7 +295,7 @@ pub trait Storage: Sized {
295295
.into_inner_contract_bytecode()
296296
.expect("Contract Bytecode Blob is of the wrong Blob type!");
297297
let contract_bytecode =
298-
tokio::task::spawn_blocking(move || compressed_contract_bytecode.decompress())
298+
linera_base::task::spawn_blocking(move || compressed_contract_bytecode.decompress())
299299
.await??;
300300
Ok(Arc::new(
301301
WasmContractModule::new(contract_bytecode, wasm_runtime).await?,
@@ -333,7 +333,8 @@ pub trait Storage: Sized {
333333
.into_inner_service_bytecode()
334334
.expect("Service Bytecode Blob is of the wrong Blob type!");
335335
let service_bytecode =
336-
tokio::task::spawn_blocking(move || compressed_service_bytecode.decompress()).await??;
336+
linera_base::task::spawn_blocking(move || compressed_service_bytecode.decompress())
337+
.await??;
337338
Ok(Arc::new(
338339
WasmServiceModule::new(service_bytecode, wasm_runtime).await?,
339340
))

0 commit comments

Comments
 (0)