pub struct ProcessVariable {
pub name: String,
pub value: RwLock<EpicsValue>,
pub subscribers: Mutex<Vec<Subscriber>>,
/* private fields */
}Expand description
A process variable hosted by the server.
Fields§
§name: String§value: RwLock<EpicsValue>§subscribers: Mutex<Vec<Subscriber>>Implementations§
Source§impl ProcessVariable
impl ProcessVariable
pub fn new(name: String, initial: EpicsValue) -> Self
Sourcepub fn set_metadata(&self, metadata: PvMetadata)
pub fn set_metadata(&self, metadata: PvMetadata)
Install (or replace) the shadow DBR_GR_/DBR_CTRL_/enum
metadata served on this PV’s snapshots. Used by the CA / PVA
gateway after fetching the upstream IOC’s control metadata. See
PvMetadata. To publish the change to downstream property
monitors, follow with Self::post_property.
Sourcepub fn metadata(&self) -> PvMetadata
pub fn metadata(&self) -> PvMetadata
Snapshot (clone) of the installed shadow metadata; empty
(Default) for a plain local PV.
Sourcepub fn set_access_hook(&self, hook: AccessHook)
pub fn set_access_hook(&self, hook: AccessHook)
Install an access hook. Replaces any previously installed hook.
Sourcepub fn access_hook(&self) -> Option<AccessHook>
pub fn access_hook(&self) -> Option<AccessHook>
Snapshot of the installed access hook (clone of the Arc), or
None. Consulted by the CA server’s compute_access; cheap and
non-async, like Self::write_hook.
Sourcepub fn set_read_hook(&self, hook: ReadHook)
pub fn set_read_hook(&self, hook: ReadHook)
Install a read hook. Replaces any previously-installed hook.
Used by the CA gateway’s no-cache mode so each downstream GET is
served by a fresh upstream fetch. See ReadHook.
Sourcepub fn read_hook(&self) -> Option<ReadHook>
pub fn read_hook(&self) -> Option<ReadHook>
Snapshot of the installed read hook (clone of the Arc), or
None. Cheap and non-async, like Self::write_hook: the read
lock is released before the cloned Arc returns, so the caller’s
subsequent await on the hook holds no lock.
Sourcepub fn set_write_hook(&self, hook: WriteHook)
pub fn set_write_hook(&self, hook: WriteHook)
Install a write hook. Replaces any previously-installed hook.
Sourcepub fn clear_write_hook(&self)
pub fn clear_write_hook(&self)
Remove any installed write hook.
Sourcepub fn write_hook(&self) -> Option<WriteHook>
pub fn write_hook(&self) -> Option<WriteHook>
Snapshot of the installed write hook (clone of the Arc), or
None if none. Used by the CA TCP write path; cheap and
non-async — the read lock is released before the cloned Arc
returns, so the caller’s subsequent await on the hook does
not hold any lock.
Sourcepub async fn get(&self) -> EpicsValue
pub async fn get(&self) -> EpicsValue
Get the current value.
Sourcepub async fn snapshot(&self) -> Snapshot
pub async fn snapshot(&self) -> Snapshot
Build a Snapshot for this bare PV.
A ProcessVariable is a non-record-backed channel: it has no
alarm engine, no DESC/EGU/PREC metadata and no timestamp user
tag of its own. The snapshot is therefore value + NO_ALARM +
wall-clock now, with user_tag = 0. Display / control / enum
metadata is None unless a proxy installed it via
Self::set_metadata (the CA / PVA gateway shadowing an
upstream IOC) — see Self::apply_metadata. Record-backed
channels build their snapshot via
RecordInstance::snapshot_for_field, which carries the record’s
own alarm/metadata. The only path that injects a non-zero alarm
onto a bare PV is Self::post_alarm (used by the gateway
adapter to surface upstream disconnect).
Sourcepub async fn read_snapshot(&self) -> Result<Snapshot, CaError>
pub async fn read_snapshot(&self) -> Result<Snapshot, CaError>
Build the snapshot served on a one-shot client GET
(CA_PROTO_READ / CA_PROTO_READ_NOTIFY).
When a ReadHook is installed (the CA gateway’s no-cache mode),
the snapshot is fetched fresh through the hook — value and its
upstream alarm status/severity and IOC timestamp together — and the
shadow’s last-known property metadata (display/control/enum) is
overlaid for the fields a DBR_TIME_* event does not carry; on hook
error the failure propagates so the server can answer ECA_GETFAIL,
matching C ca-gateway forwarding each read to the IOC under
-no_cache (gateVc.cc:1361-1369, gatePv.cc:976/:1789-1794).
Without a hook this is exactly Self::snapshot wrapped in Ok,
so the GET path is unchanged for every record-backed and cached PV.
Only the GET path calls this; monitor fan-out, the initial monitor
event, and access-rights re-posts keep using Self::snapshot
(the stored value), so a no-cache PV still backs a downstream
monitor with its upstream subscription’s events rather than a
per-event upstream get.
Sourcepub async fn set(&self, new_value: EpicsValue)
pub async fn set(&self, new_value: EpicsValue)
Set a new value and notify all subscribers.
Sourcepub async fn set_snapshot(&self, snapshot: Snapshot)
pub async fn set_snapshot(&self, snapshot: Snapshot)
Set value from a full snapshot (value + alarm + timestamp) and notify
all subscribers. Used by the CA gateway forwarding task to propagate
the upstream alarm status/severity and IOC timestamp to downstream
monitors. Mirrors gateVcData::setEventData + vcPostEvent in the
C ca-gateway: the incoming dbr_time_xxx GDD carries all three fields.
Sourcepub async fn post_alarm(&self, severity: u16, status: u16)
pub async fn post_alarm(&self, severity: u16, status: u16)
Push a fresh monitor event holding the current value but with the supplied alarm severity/status. Used by the PVA / CA gateway adapter to surface upstream-disconnect to downstream monitor subscribers without dropping the simple PV (which would force every downstream client into ECA_DISCONN + reconnect storms when the upstream is just briefly unreachable). Mirrors gatePvData::death’s “alarm-post” alternative discussed in the C++ ca-gateway audit.
Sourcepub async fn post_property(&self, snapshot: Snapshot)
pub async fn post_property(&self, snapshot: Snapshot)
Post a DBE_PROPERTY monitor event carrying the decoded upstream
CTRL event snapshot — its value plus the upstream status /
severity and timestamp — overlaid with the installed shadow
metadata, so downstream property-change monitors re-read the units /
precision / limits / enum labels with the upstream alarm state.
Used by the CA / PVA gateway when an upstream DBE_PROPERTY event
fires (metadata changed) after it has refreshed the shadow PV via
Self::set_metadata. The caller supplies the snapshot rather than
this method synthesising one: C ca-gateway decodes the upstream
DBR_CTRL_* callback and re-posts the value with setStatSevr()
status/severity preserved (gatePv.cc:2413-2438,
runValueDataCB), leaving the timestamp as the control DBR carries
none — it must NOT be replaced with a fresh NO_ALARM /
wall-clock-now snapshot just because metadata changed. Pass the
timestamp the upstream value carried (the control event has none of
its own); pass status/severity from the upstream CTRL payload.
Property events are a distinct class from value/alarm: only
DBE_PROPERTY subscribers receive them.
Sourcepub async fn add_subscriber(
&self,
sid: u32,
data_type: DbFieldType,
mask: u16,
) -> Option<Receiver<MonitorEvent>>
pub async fn add_subscriber( &self, sid: u32, data_type: DbFieldType, mask: u16, ) -> Option<Receiver<MonitorEvent>>
Add a subscriber. Returns the receiver for monitor events,
or None when the per-PV subscriber cap has been reached
(defends against a misbehaving client opening many
MONITOR ops against one shared PV; per-channel cap limits
channels but not subscriber rows on a single PV). Operators
override the cap via EPICS_CAS_MAX_SUBSCRIBERS_PER_PV
(default 1024 — large enough for any realistic dashboard
fan-out, small enough to bound memory under abuse).
Channel depth defaults to 64 events; the operator can lift the
cap via EPICS_CAS_MAX_EVENTS_PER_CHAN for sites that need
deeper coalescing buffers. C rsrv does not advertise this knob
(its queue is internally fixed) — exposing it lets us tune
memory vs latency for slow-viewer workloads.
Sourcepub async fn attach_filters_to_subscriber(&self, sid: u32, filters: FilterChain)
pub async fn attach_filters_to_subscriber(&self, sid: u32, filters: FilterChain)
attach a channel-filter chain to an already-added
subscriber (looked up by sid). The CA server first
add_subscribers, then attaches the chain parsed from the
channel’s .{...} suffix — symmetric with the record-field
RecordInstance::attach_filter_to_last_subscriber path, so a
SimplePv monitor runs the SAME filter chain as a record-field
monitor instead of the empty default FilterChain that
add_subscriber installs. Update delivery
(Self::notify_subscribers / Self::post_alarm) already
applies sub.filters; this is the missing wiring that populates
it.
The caller passes a FRESH chain per subscriber so stateful
filters (dbnd last-value, dec counter, sync state) stay
isolated across subscribers. An empty chain is a no-op (keeps the
default). No-op when no subscriber matches sid (e.g. it was
reaped between add and attach).
Sourcepub async fn remove_subscriber(&self, sid: u32)
pub async fn remove_subscriber(&self, sid: u32)
Remove a subscriber by subscription ID.
Sourcepub async fn pop_coalesced(&self, sid: u32) -> Option<MonitorEvent>
pub async fn pop_coalesced(&self, sid: u32) -> Option<MonitorEvent>
Take any pending coalesced overflow value for the given subscriber.
Called by the per-subscription forwarder task after each rx.recv()
and folded in via coalesce_consume, which drains the now-stale
queue tail so a slow consumer converges on the latest known value
without ever delivering it before older queued values.