Skip to content

fix(transport): shared VISA transport overwhelmed by concurrent instrument publishers #555

Description

@wharwood

Problem

When a shared-transport device (e.g. the bidirectional EA PSB10000, which vends both a PSUDriverBase .source view and an ELoadDriverBase .sink view over one VisaDriver) has publishers/background daemons running on more than one of its Instro* views, each view's Instrument background daemon runs on its own independent thread with its own poll_interval, unaware of any sibling instrument sharing the same underlying transport.

TransportBase/VisaDriver (instro/lib/transports/) already serialize concurrent access with a per-call RLock, so wire bytes never interleave — but nothing limits the combined rate of commands issued against one transport. Two independently-polling views can issue back-to-back commands fast enough to overrun the physical device's command/error-queue buffer. On the EA PSB10000 specifically, SYST:ERR? is queried immediately after every write/query (EAPSB10000Visa._write_checked/_query_checked), and the device queues errors asynchronously (~10-15ms per manual, ~100ms empirically safe per tests/psu/ea/test_ea_psb10000_hardware.py) — so concurrent pollers can outrun that queue and corrupt/drop error-check reads.

This isn't PSB-specific: any device class that vends multiple category views over one shared transport (per the "device serving more than one category" pattern in AGENTS.md) is exposed to the same failure once more than one view runs a background daemon/publisher.

Fix direction

Add a minimum inter-command spacing enforced inside the transport's own locked critical section (TransportBase/VisaDriver), so it throttles at the shared-resource level regardless of how many Instrument instances/threads are contending for it. This generalizes to any shared-transport driver without touching per-instrument polling config or the Instrument daemon architecture.

Repro

  • Construct an EAPSB10000Visa, get both .source (wrap in InstroPSU) and .sink (wrap in InstroELoad), attach publishers/background daemons to both, start() both with default poll_interval=1.0.
  • Observe SYST:ERR? failures / dropped or garbled responses on the shared VISA line as both daemons' ticks race.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions