Skip to content

Commit 713dfd4

Browse files
committed
Fix ProxySession message id mis-routing
Signed-off-by: Andrew Stein <[email protected]>
1 parent 871dcd7 commit 713dfd4

File tree

9 files changed

+109
-18
lines changed

9 files changed

+109
-18
lines changed

.cargo/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ rustflags = ["--cfg=web_sys_unstable_apis"]
66
target-dir = "rust/target"
77

88
[target.wasm32-unknown-unknown]
9-
runner = 'wasm-bindgen-test-runner'
109
rustflags = [
10+
"--cfg=getrandom_backend=\"wasm_js\"",
1111
"--cfg=web_sys_unstable_apis",
1212
"-Ctarget-feature=+bulk-memory,+simd128,+relaxed-simd,+reference-types",
1313
]

Cargo.lock

Lines changed: 50 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/perspective-client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ itertools = { version = "0.10.1" }
6262
nanoid = { version = "0.4.0" }
6363
paste = { version = "1.0.12" }
6464
prost-types = { version = "0.12.3" }
65+
getrandom = { version = "0.3", features = ["wasm_js"] }
6566
serde = { version = "1.0", features = ["derive"] }
6667
serde_bytes = { version = "0.11" }
6768
serde_json = { version = "1.0.107", features = ["raw_value"] }

rust/perspective-client/src/rust/client.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,13 @@ impl Client {
127127
Box::pin(async move { send_request(bytes).await })
128128
});
129129

130+
let mut buf = [0u8; 4];
131+
getrandom::fill(&mut buf).unwrap();
132+
let seed = u32::from_ne_bytes(buf);
133+
130134
Client {
131135
features: Arc::default(),
132-
id_gen: Arc::new(AtomicU32::new(1)),
136+
id_gen: Arc::new(AtomicU32::new(seed)),
133137
send,
134138
subscriptions: Subscriptions::default(),
135139
subscriptions_errors: Arc::default(),
@@ -256,7 +260,12 @@ impl Client {
256260
/// Generate a message ID unique to this client.
257261
pub(crate) fn gen_id(&self) -> u32 {
258262
self.id_gen
259-
.fetch_add(1, std::sync::atomic::Ordering::Acquire)
263+
.fetch_update(
264+
std::sync::atomic::Ordering::Relaxed,
265+
std::sync::atomic::Ordering::Relaxed,
266+
|old| Some(if old == u32::MAX { 0_u32 } else { old + 1 }),
267+
)
268+
.unwrap()
260269
}
261270

262271
pub(crate) async fn unsubscribe(&self, update_id: u32) -> ClientResult<()> {

rust/perspective-js/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ futures = "0.3.28"
5757
derivative = "2.2.0"
5858
getrandom = { version = "0.2", features = ["js"] }
5959
js-intern = "0.3.1"
60-
js-sys = "0.3.64"
60+
js-sys = "0.3.77"
6161
prost = { version = "0.12.3", default-features = false, features = [
6262
"prost-derive",
6363
"std",
@@ -79,7 +79,7 @@ wasm-bindgen-derive = "0.3.0"
7979
wasm-bindgen-futures = "0.4.41"
8080

8181
[dependencies.web-sys]
82-
version = "0.3.64"
82+
version = "0.3.77"
8383
features = [
8484
"console",
8585
"Blob",

rust/perspective-js/src/rust/utils/browser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ pub mod global {
3434
}
3535

3636
pub fn clipboard() -> web_sys::Clipboard {
37-
navigator().clipboard().unwrap()
37+
navigator().clipboard()
3838
}
3939
}

rust/perspective-python/perspective/tests/server/test_session.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,39 @@ def handle_response(bytes):
7272
assert (await table.size()) == 3
7373
table2.update([{"a": 4, "d": 5}])
7474
assert (await table.size()) == 4
75+
76+
@pytest.mark.asyncio
77+
async def test_dismabiguate_message_ids_in_proxy_session(self):
78+
"""tests concurrent calls from clients on Session + ProxySession"""
79+
server = Server()
80+
client = server.new_local_client()
81+
82+
def send_response(bytes):
83+
import asyncio
84+
85+
asyncio.create_task(sub_client.handle_response(bytes))
86+
87+
async def send_request(bytes):
88+
await sub_session.handle_request_async(bytes)
89+
await sub_session.poll_async()
90+
91+
sub_session = ProxySession(client, send_response)
92+
sub_client = AsyncClient(send_request, sub_session.close)
93+
94+
table = client.table("x\n1", name="test_table")
95+
table2 = await sub_client.open_table("test_table")
96+
view = table.view()
97+
view2 = await table2.view()
98+
99+
sentinel = []
100+
101+
def callback1(*args):
102+
sentinel.append("Callback 1")
103+
104+
def callback2(*args):
105+
sentinel.append("Callback 2")
106+
107+
view.on_update(callback1)
108+
await view2.on_update(callback2)
109+
await table2.update("x\n2")
110+
assert sentinel == ["Callback 1", "Callback 2"]

rust/perspective-python/src/client/proxy_session.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ impl ProxySession {
7171
Ok(())
7272
}
7373

74+
pub async fn poll_async(&self) -> PyResult<()> {
75+
self.0.poll().await.into_pyerr()?;
76+
Ok(())
77+
}
78+
7479
pub fn close(&self, py: Python<'_>) -> PyResult<()> {
7580
self.0.clone().close().py_block_on(py);
7681
Ok(())

rust/perspective-viewer/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ itertools = "0.10.1"
7777
js-intern = "0.3.1"
7878

7979
# JavaScript stdlib bindings
80-
js-sys = "0.3.64"
80+
js-sys = "0.3.77"
8181

8282
# Parse ExprTK for syntax highlighting.
8383
nom = "7.1.1"
@@ -119,7 +119,7 @@ wasm-bindgen-futures = "0.4.41"
119119
yew = { version = "0.21.0", features = ["csr"] }
120120

121121
# Browser stdlib bindings
122-
web-sys.version = "0.3.64"
122+
web-sys.version = "0.3.77"
123123

124124
# Browser stdlib bindings
125125
web-sys.features = [

0 commit comments

Comments
 (0)