Skip to main content

Pool

Struct Pool 

Source
pub struct Pool { /* private fields */ }
Expand description

Multi-conn driver/dispatcher:

  • 单线程持有 Proactor;
  • 持有 Vec<Option<ConnectionState>> slot table;
  • drain CQE;
  • 从 CQE user_data 中解析 token,做 generation guard;
  • 找到对应 ConnectionState(真正干活的是 ConnectionState);
  • 调用 conn.handle_completion...

Slot table 路由:slot id 直接索引 conns,O(1)。generation guard 让 stale handle / late CQE 无法命中复用后的 slot。

Implementations§

Source§

impl Pool

Source

pub fn new(cfg: PoolConfig) -> Result<Self, ProactorError>

Source

pub fn connect_blocking( &mut self, cfg: ConnectionConfig, ) -> Result<ConnHandle, ConnectionError>

加一条 conn,阻塞跑到 State::Open 才返。失败时 slot 置 None (中途产生的 fd 由 ConnectionState drop 关闭)。

io_uring/proactor 参数来自 PoolConfig;connection runtime ids are assigned internally.

Source

pub fn connect_blocking_to( &mut self, cfg: ConnectionConfig, addr: SocketAddr, ) -> Result<ConnHandle, ConnectionError>

connect_blocking,但跳过 DNS。 这是一个同步建连便利 API,适合“还没进入行情 hot loop”之前使用。 不要在 hot pool 活跃收包时动态 blocking connect; 初始化阶段用 submit_connect_to() 并发建连。

Source

pub fn submit_connect( &mut self, cfg: ConnectionConfig, ) -> Result<ConnHandle, ConnectionError>

非阻塞 connect:在 Pool 里新增一条连接,并把 TCP connect SQE 提交给 io_uring,但不等待连接完成。 仅提交 connect SQE 并 reserve 一个 slot,立刻返回 ConnHandle。 后续靠 caller pump() 推进 handshake,直到 state(h) == Open(或 Closed 表失败)。

用途:N 条 conn 并发 handshake —— 单 connect_blocking 串行 N 次的话, TLS handshake 30 ms × N 全是开机延迟。submit 模式下 N 条同时跑,总等 时间 ≈ 一次 handshake。

let h1 = pool.submit_connect(cfg1)?;
let h2 = pool.submit_connect(cfg2)?;
loop {
    pool.pump(|_, _| {})?;
    if pool.state(h1) == Some(State::Open) && pool.state(h2) == Some(State::Open) {
        break;
    }
    if matches!(pool.state(h1), Some(State::Closed))
        || matches!(pool.state(h2), Some(State::Closed)) {
        // 处理早夭
    }
}
Source

pub fn submit_connect_to( &mut self, cfg: ConnectionConfig, addr: SocketAddr, ) -> Result<ConnHandle, ConnectionError>

submit_connect,跳过 DNS。 production multi-conn startup API

Source

pub fn remove_conn(&mut self, h: ConnHandle) -> Result<(), ConnectionError>

强制移除一条连接并释放其 Pool slot / bgid 供后续重连复用。

这是运行时诊断/故障恢复 API,不执行 WebSocket close handshake;如果需要 协议级优雅关闭,先调用 Self::initiate_close 并继续 pump close handshake。 stale handle 或已被移除的 slot 返回 ConnectionError::InvalidState.

Source

pub fn reconnect( &mut self, old: ConnHandle, cfg: ConnectionConfig, ) -> Result<ConnHandle, ConnectionError>

Blocking reconnect convenience API. Resolves DNS, removes old, submits a fresh connection, then drives it to Open.

Source

pub fn reconnect_to( &mut self, old: ConnHandle, cfg: ConnectionConfig, addr: SocketAddr, ) -> Result<ConnHandle, ConnectionError>

Blocking reconnect convenience API with caller-provided address.

Production hot loops should prefer Self::submit_reconnect_to so the main pump loop keeps processing other connections while the new TCP/TLS/WS handshake progresses.

Source

pub fn submit_reconnect( &mut self, old: ConnHandle, cfg: ConnectionConfig, ) -> Result<ConnHandle, ConnectionError>

Non-blocking reconnect. Resolves DNS, removes old, submits the new connection, then returns immediately.

Source

pub fn submit_reconnect_to( &mut self, old: ConnHandle, cfg: ConnectionConfig, addr: SocketAddr, ) -> Result<ConnHandle, ConnectionError>

Non-blocking reconnect with caller-provided address.

The old connection is removed first; if creating/submitting the new connection fails, the old connection remains gone and the slot/bgid are returned to the freelists. This API is for diagnostic reconnect, not keep-old-until-new-open cutover.

Source

pub fn send_text( &mut self, h: ConnHandle, payload: &[u8], ) -> Result<(), ConnectionError>

Source

pub fn send_binary( &mut self, h: ConnHandle, payload: &[u8], ) -> Result<(), ConnectionError>

Source

pub fn send_ping( &mut self, h: ConnHandle, payload: &[u8], ) -> Result<(), ConnectionError>

Source

pub fn send_pong( &mut self, h: ConnHandle, payload: &[u8], ) -> Result<(), ConnectionError>

Source

pub fn initiate_close( &mut self, h: ConnHandle, code: u16, reason: &str, ) -> Result<(), ConnectionError>

Source

pub fn pump<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: FnMut(ConnHandle, WsEvent<'_>),

Source

pub fn pump_nowait<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: FnMut(ConnHandle, WsEvent<'_>),

Source

pub fn pump_spin<F>( &mut self, spin_iters: usize, sink: F, ) -> Result<bool, ConnectionError>
where F: FnMut(ConnHandle, WsEvent<'_>),

Busy-poll 版本的 pump

先提交 pending send / multishot rearm,然后最多轮询 spin_iters + 1 次 CQ ring;期间不调用 Proactor::wait_for_cqe,因此不会为了等待 completion 进入 io_uring_enter(GETEVENTS)。这只适合 isolated CPU 上的 高频 steady-state loop;低负载下会白烧 CPU。

返回值表示这一轮是否处理到了任何 CQE 或 WS event。caller 可以据此决定 继续 busy-spin,或 fallback 到阻塞 pump

Source

pub fn pump_data<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEvent<'a>),

Data-only pump:跟 pump 一样推进 io_uring 和完整 WebSocket 状态机,但只把业务 data message 交给 sink。

Text JSON 和 Binary SBE 都会被分发;Ping/Pong/Close、fragmentation、 auto-pong、UTF-8 校验等仍由 crate::ws::WsClient 正常处理。适合交易所 行情主循环:业务代码只关心 data payload,但连接层不能忽略 control frame。

Source

pub fn pump_data_nowait<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEvent<'a>),

pump_data,但 wait_for_cqe(0) —— 立刻返回, 没新 CQE 也不阻塞。配合 close handshake / 退出 cleanup 用。

Source

pub fn pump_data_marked<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEvent<'a>),

Marked data-only pump. This is the opt-in observability variant of Self::pump_data; the default API does not read clocks or construct timing metadata.

Source

pub fn pump_data_marked_nowait<F>( &mut self, sink: F, ) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEvent<'a>),

Non-blocking marked data-only pump.

Source

pub fn pump_data_batches<F>(&mut self, sink: F) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEventBatch<'a>),

Batch variant of Self::pump_data.

The callback receives fixed-capacity batches of data messages. Direct plaintext chunks can produce multi-message batches; fallback protocol paths may still produce one-message batches. Use WsDataEventBatch::is_chunk_end to know when all data messages from the current plaintext chunk have been delivered.

Source

pub fn pump_data_batches_nowait<F>( &mut self, sink: F, ) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEventBatch<'a>),

Non-blocking batch variant of Self::pump_data_nowait.

Source

pub fn pump_data_marked_batches<F>( &mut self, sink: F, ) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEventBatch<'a>),

Batch variant of Self::pump_data_marked.

Batch delivery measures sink service at the batch boundary. Messages in one emitted batch share the same chunk_prior_sink_service_nanos; use Self::pump_data_marked for strict per-message sink queuing metrics. Use WsMarkedDataEventBatch::is_chunk_end to coalesce all data messages from the current plaintext chunk without waiting for the next chunk.

Source

pub fn pump_data_marked_batches_nowait<F>( &mut self, sink: F, ) -> Result<(), ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEventBatch<'a>),

Non-blocking batch variant of Self::pump_data_marked_nowait.

Source

pub fn pump_data_spin<F>( &mut self, spin_iters: usize, sink: F, ) -> Result<bool, ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEvent<'a>),

Busy-poll 版本的 pump_data

本方法只轮询 mmap 出来的 CQ ring,不调用 Proactor::wait_for_cqe。 代价是 caller 所在线程会在没有 CQE 时持续占 CPU。

返回值表示这一轮是否处理到了任何 CQE 或 WS event。

Source

pub fn pump_data_spin_batches<F>( &mut self, spin_iters: usize, sink: F, ) -> Result<bool, ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsDataEventBatch<'a>),

Busy-poll batch variant of Self::pump_data_spin.

Source

pub fn pump_data_spin_marked<F>( &mut self, spin_iters: usize, sink: F, ) -> Result<bool, ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEvent<'a>),

Busy-poll marked data-only pump.

Use this when measuring transport/TLS/WS stage latency. It carries crate::observability::DataEventMeta with each Text/Binary payload. Unmarked pump_data_spin stays free of clock reads.

Source

pub fn pump_data_spin_marked_batches<F>( &mut self, spin_iters: usize, sink: F, ) -> Result<bool, ConnectionError>
where F: for<'a> FnMut(ConnHandle, WsMarkedDataEventBatch<'a>),

Busy-poll batch variant of Self::pump_data_spin_marked.

See Self::pump_data_marked_batches for batch observability semantics.

Source

pub fn state(&self, h: ConnHandle) -> Option<State>

Source

pub fn conn_count(&self) -> usize

当前 active conn 数(不含空闲 slot)。

Source

pub fn ingress_stats(&self, h: ConnHandle) -> Option<IngressStats>

Returns opt-in ingress diagnostics for a live connection.

Source

pub fn prometheus_metrics(&self) -> String

Render a Prometheus text exposition snapshot for all live connections.

Source

pub fn write_prometheus_metrics<W: Write>(&self, out: &mut W) -> Result

Write a Prometheus text exposition snapshot for all live connections.

Source

pub fn prometheus_metrics_and_reset_interval(&mut self) -> String

Render interval Prometheus metrics and reset interval latency histograms.

Source

pub fn write_prometheus_metrics_and_reset_interval<W: Write>( &mut self, out: &mut W, ) -> Result

Write interval Prometheus metrics and reset interval latency histograms.

Ingress counters remain lifetime cumulative; only latency histograms are reset after a successful write.

Trait Implementations§

Source§

impl Debug for Pool

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Pool

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Pool

§

impl !Send for Pool

§

impl !Sync for Pool

§

impl !UnwindSafe for Pool

§

impl Freeze for Pool

§

impl Unpin for Pool

§

impl UnsafeUnpin for Pool

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more