1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! PVA-to-PVA proxy gateway.
//!
//! Mirrors the C++ `pva2pva/p2pApp` gateway at the architectural
//! level: one upstream [`epics_pva_rs::client::PvaClient`] keeps a
//! cache of channels (one per upstream PV name), one downstream
//! [`epics_pva_rs::server_native::PvaServer`] accepts client
//! connections and forwards GET / PUT / MONITOR / GET_FIELD ops
//! through the cache.
//!
//! ## Topology
//!
//! ```text
//! downstream PVA clients
//! │
//! ▼
//! ┌──────────────────┐ ┌────────────────────────┐
//! │ PvaServer (DS) │ uses │ GatewayChannelSource │
//! │ in pva-rs │────────▶│ (impl ChannelSource) │
//! └──────────────────┘ └──────────┬─────────────┘
//! │ lookup / get / put
//! ▼
//! ┌────────────────────────┐
//! │ ChannelCache │
//! │ PV → UpstreamEntry │
//! │ ├ broadcast::Sender │ fan-out
//! │ └ monitor task │ (one per PV)
//! └──────────┬─────────────┘
//! │ pvmonitor / pvget / pvput
//! ▼
//! ┌────────────────────────┐
//! │ PvaClient (US) │
//! │ in pva-rs │
//! └──────────┬─────────────┘
//! ▼
//! upstream PVA servers
//! ```
//!
//! ## Lifecycle
//!
//! - **Search** — downstream `has_pv` triggers
//! [`channel_cache::ChannelCache::lookup`], which opens an upstream
//! monitor (one per PV) and waits for the first event before
//! reporting "found". Subsequent searches for the same PV hit the
//! fast path.
//! - **GET** — uses the cached snapshot; same value the upstream
//! server would return on a fresh GET.
//! - **MONITOR** — every downstream subscriber receives a fresh
//! `tokio::sync::broadcast::Receiver`. Slow subscribers see
//! lagged events; the next upstream tick resyncs.
//! - **PUT** — forwarded through the upstream `PvaClient::pvput`,
//! reusing the existing upstream channel (no fresh CREATE_CHAN
//! round-trip per write).
//! - **Cleanup** — a 30 s background tick drops entries that have
//! neither been touched since the previous tick nor have any live
//! downstream subscribers. Mirrors p2pApp `cacheClean`.
//! - **Control (B6)** — when a `control_prefix` is set,
//! [`control::ControlSource`] exposes read-only diagnostic PVs plus
//! credentialed control RPCs (`<prefix>:flush` / `:drop` /
//! `:reload`) that flush the channel cache, drop one entry, or
//! hot-swap the gateway-side ACF policy.
//!
//! ## Quick start
//!
//! ```no_run
//! use std::sync::Arc;
//! use epics_bridge_rs::pva_gateway::{PvaGateway, PvaGatewayConfig};
//!
//! # async fn run() -> epics_bridge_rs::pva_gateway::error::GwResult<()> {
//! let gw = PvaGateway::start(PvaGatewayConfig::default())?;
//! gw.run().await?;
//! # Ok(())
//! # }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use GatewayChannelSource;