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<EventReader>
pub async fn add_subscriber( &self, sid: u32, data_type: DbFieldType, mask: u16, ) -> Option<EventReader>
Add an in-process subscriber, attached to an event queue of its own.
C db_add_event(ctx, ...) puts a monitor on the queue chain of the
event_user (client) that owns it. An in-process consumer is its own
client, so it gets its own EventUser — nothing else shares its
queue, and flow control (a CA circuit concept) never engages on it.
The CA server, whose subscriptions DO share one circuit-wide queue, uses
Self::add_subscriber_on.
Sourcepub async fn add_subscriber_on(
&self,
user: &EventUser,
sid: u32,
data_type: DbFieldType,
mask: u16,
) -> Option<EventReader>
pub async fn add_subscriber_on( &self, user: &EventUser, sid: u32, data_type: DbFieldType, mask: u16, ) -> Option<EventReader>
Add a subscriber whose events are queued on user’s event queue —
C db_add_event with the circuit’s event_user as context. Every
subscription on one CA circuit shares that queue, and therefore its
nDuplicates: a duplicate queued for one of them releases the
EVENTS_OFF drain for all of them (dbEvent.c:947).
Returns None when the per-PV subscriber cap is reached (defends
against a misbehaving client opening many MONITOR ops against one shared
PV; the per-channel cap limits channels but not subscriber rows on a
single PV). Operators override it via EPICS_CAS_MAX_SUBSCRIBERS_PER_PV.
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.