omq-backend-rust 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/ext/omq_backend_rust/Cargo.toml +1 -1
- data/ext/omq_backend_rust/src/runtime.rs +51 -13
- data/lib/omq/rust/engine.rb +19 -1
- data/lib/omq/rust/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b22c5a39d466ddff0ea811bfadff93fe58e64c3ea08bb213f61419e5efd13cc6
|
|
4
|
+
data.tar.gz: '09ef0d2306516c3809a957f61e234360d9f2bbe34b0389cf874c8d5cdc87abc8'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bae7c0181f01e714d3fbbb11546bb84dc6642d77661734e5d5eaa5467af153a5437b0a9af1ff0d1b8f894609928d7952a83bcb492ef299e327253acdc6a1f85d
|
|
7
|
+
data.tar.gz: b787de3962b49bf2c784596f8fd82901e0323e74270915ba051359eb73a46022389726cea92b1a6364c7780eaf296a457d8355d90507503a5690f4de4de8410b
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.1.7] - 2026-08-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Restored Rust/Ruby backend interop coverage.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Updated to `omq-tokio` 0.21.0.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Drained the Ruby-to-Tokio send pump before native socket close.
|
|
18
|
+
- Released Rust send ring slots before awaiting native sends, avoiding
|
|
19
|
+
high-throughput stalls under `omq-tokio` 0.21.0 backpressure.
|
|
20
|
+
- Waited for Rust peer registration before resolving `peer_connected`.
|
|
21
|
+
|
|
5
22
|
## [0.1.6] - 2026-08-01
|
|
6
23
|
|
|
7
24
|
### Added
|
|
@@ -19,7 +19,7 @@ zstd = ["omq-tokio/zstd"]
|
|
|
19
19
|
|
|
20
20
|
[dependencies]
|
|
21
21
|
omq-proto = { version = "=0.25.0", default-features = false }
|
|
22
|
-
omq-tokio = { version = "=0.
|
|
22
|
+
omq-tokio = { version = "=0.21.0", default-features = false }
|
|
23
23
|
tokio = { version = "1.52.0", features = ["rt", "rt-multi-thread", "time", "sync", "io-util", "net"] }
|
|
24
24
|
yring = { version = "0.3.11", features = ["async"] }
|
|
25
25
|
|
|
@@ -299,20 +299,15 @@ pub fn materialize(
|
|
|
299
299
|
let job: Job = Box::new(move || {
|
|
300
300
|
let sock = Arc::new(InnerSocket::new(socket_type, options));
|
|
301
301
|
|
|
302
|
-
const SEND_YIELD_INTERVAL: u32 = 256;
|
|
303
302
|
let s = sock.clone();
|
|
304
303
|
let sn = send_notify.clone();
|
|
305
304
|
let send_pump = tokio::spawn(async move {
|
|
306
|
-
|
|
307
|
-
let mut batch = 0u32;
|
|
305
|
+
let mut send_cons = send_cons;
|
|
308
306
|
while let Some(msg) = futures::StreamExt::next(&mut send_cons).await {
|
|
309
|
-
|
|
307
|
+
send_cons.release();
|
|
310
308
|
sn.notify();
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
batch = 0;
|
|
314
|
-
tokio::task::yield_now().await;
|
|
315
|
-
}
|
|
309
|
+
let _ = s.send(msg).await;
|
|
310
|
+
tokio::task::yield_now().await;
|
|
316
311
|
}
|
|
317
312
|
sn.notify();
|
|
318
313
|
});
|
|
@@ -343,6 +338,7 @@ pub fn materialize(
|
|
|
343
338
|
});
|
|
344
339
|
|
|
345
340
|
let monitor_sock = sock.clone();
|
|
341
|
+
let peer_ready_sock = sock.clone();
|
|
346
342
|
let monitor_pump = tokio::spawn(async move {
|
|
347
343
|
let mut stream = monitor_sock.monitor();
|
|
348
344
|
let mut peer_count: u32 = 0;
|
|
@@ -359,6 +355,7 @@ pub fn materialize(
|
|
|
359
355
|
had_peers = true;
|
|
360
356
|
if !peer_connected_fired {
|
|
361
357
|
peer_connected_fired = true;
|
|
358
|
+
let _ = peer_ready_sock.connections().await;
|
|
362
359
|
peer_connected_notify.force_wake();
|
|
363
360
|
}
|
|
364
361
|
}
|
|
@@ -374,6 +371,12 @@ pub fn materialize(
|
|
|
374
371
|
subscriber_joined_notify.force_wake();
|
|
375
372
|
}
|
|
376
373
|
}
|
|
374
|
+
omq_tokio::MonitorEvent::JoinReceived { .. } => {
|
|
375
|
+
if !subscriber_joined_fired {
|
|
376
|
+
subscriber_joined_fired = true;
|
|
377
|
+
subscriber_joined_notify.force_wake();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
377
380
|
_ => {}
|
|
378
381
|
}
|
|
379
382
|
|
|
@@ -432,24 +435,59 @@ pub fn destroy_socket(
|
|
|
432
435
|
io_threads: usize,
|
|
433
436
|
sock: Arc<InnerSocket>,
|
|
434
437
|
send_prod: Mutex<yring::AsyncProducer<omq_tokio::Message>>,
|
|
435
|
-
send_pump: JoinHandle<()>,
|
|
438
|
+
mut send_pump: JoinHandle<()>,
|
|
436
439
|
recv_pump: JoinHandle<()>,
|
|
437
440
|
monitor_pump: JoinHandle<()>,
|
|
438
441
|
linger: Option<Duration>,
|
|
439
442
|
) {
|
|
440
443
|
recv_pump.abort();
|
|
441
444
|
monitor_pump.abort();
|
|
442
|
-
send_pump.abort();
|
|
443
|
-
drop(send_prod);
|
|
444
445
|
let Ok(handle) = (|| -> std::result::Result<Handle, ()> { Ok(ensure_runtime(io_threads)) })()
|
|
445
446
|
else {
|
|
447
|
+
send_pump.abort();
|
|
448
|
+
drop(send_prod);
|
|
446
449
|
return;
|
|
447
450
|
};
|
|
448
451
|
let close_timeout = linger
|
|
449
452
|
.unwrap_or(Duration::from_secs(30))
|
|
450
453
|
.max(Duration::from_millis(10));
|
|
451
|
-
|
|
454
|
+
let fut = async move {
|
|
455
|
+
drop(send_prod);
|
|
456
|
+
if tokio::time::timeout(close_timeout, &mut send_pump)
|
|
457
|
+
.await
|
|
458
|
+
.is_err()
|
|
459
|
+
{
|
|
460
|
+
send_pump.abort();
|
|
461
|
+
let _ = send_pump.await;
|
|
462
|
+
}
|
|
463
|
+
|
|
452
464
|
let s = Arc::try_unwrap(sock).unwrap_or_else(|arc| (*arc).clone());
|
|
453
465
|
let _ = tokio::time::timeout(close_timeout, s.close()).await;
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
let (otx, orx) = flume::bounded::<()>(1);
|
|
469
|
+
handle.spawn(async move {
|
|
470
|
+
fut.await;
|
|
471
|
+
let _ = otx.send(());
|
|
454
472
|
});
|
|
473
|
+
|
|
474
|
+
struct RecvBox {
|
|
475
|
+
rx: flume::Receiver<()>,
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
extern "C" fn blocking_recv(data: *mut libc::c_void) -> *mut libc::c_void {
|
|
479
|
+
let rd = unsafe { &mut *(data as *mut RecvBox) };
|
|
480
|
+
let _ = rd.rx.recv();
|
|
481
|
+
std::ptr::null_mut()
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
let mut rd = RecvBox { rx: orx };
|
|
485
|
+
unsafe {
|
|
486
|
+
rb_sys::rb_thread_call_without_gvl(
|
|
487
|
+
Some(blocking_recv),
|
|
488
|
+
&mut rd as *mut RecvBox as *mut libc::c_void,
|
|
489
|
+
None,
|
|
490
|
+
std::ptr::null_mut(),
|
|
491
|
+
);
|
|
492
|
+
}
|
|
455
493
|
}
|
data/lib/omq/rust/engine.rb
CHANGED
|
@@ -19,7 +19,7 @@ module OMQ
|
|
|
19
19
|
@peer_connected = Async::Promise.new
|
|
20
20
|
@all_peers_gone = Async::Promise.new
|
|
21
21
|
@subscriber_joined = Async::Promise.new
|
|
22
|
-
@connections =
|
|
22
|
+
@connections = {}
|
|
23
23
|
@closed = false
|
|
24
24
|
@parent_task = nil
|
|
25
25
|
@on_io_thread = false
|
|
@@ -222,6 +222,7 @@ module OMQ
|
|
|
222
222
|
monitor_io.wait_readable
|
|
223
223
|
monitor_io.read_nonblock(256, exception: false)
|
|
224
224
|
while (data = @native.try_recv_monitor)
|
|
225
|
+
track_connection_event(data)
|
|
225
226
|
@monitor_queue.enqueue(MonitorEvent.new(**data))
|
|
226
227
|
end
|
|
227
228
|
end
|
|
@@ -229,6 +230,23 @@ module OMQ
|
|
|
229
230
|
end
|
|
230
231
|
|
|
231
232
|
|
|
233
|
+
def track_connection_event(data)
|
|
234
|
+
detail = data[:detail] || {}
|
|
235
|
+
connection_id = detail[:connection_id]
|
|
236
|
+
|
|
237
|
+
case data[:type]
|
|
238
|
+
when :handshake_succeeded
|
|
239
|
+
@connections[connection_id || Object.new] = true
|
|
240
|
+
when :disconnected
|
|
241
|
+
if connection_id
|
|
242
|
+
@connections.delete(connection_id)
|
|
243
|
+
else
|
|
244
|
+
@connections.shift
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
|
|
232
250
|
def extract_options
|
|
233
251
|
h = {}
|
|
234
252
|
h["send_hwm"] = @options.send_hwm
|
data/lib/omq/rust/version.rb
CHANGED