fix(ab-transport): per-pool diagnostics + per-device open-attempt limit, CIP-level close recycle, CipConnection/pool test gaps (#566, #581)
- Process-wide CipConnection statics (ForwardOpenCount, Forward Close counts, RequestsSent, exchange stats, OpenAttempts, OpenAttemptBudget) move to an instance ConnectionDiagnostics owned by each DeviceSessionPool (and by a stand-alone CipConnection). The open-attempt budget becomes a disposable per-DeviceKey limit (LimitOpenAttempts); the differential harness scopes one to the press under test. - LibplctagOrphanRelease.ForceRootingForTest is gone: ReleaseIfOrphaned(tag, canReadHandles) overload. - A connected reply with general 0x01 / extended 0x0107 or 0x0203 (target no longer holds the class-3 connection, TCP still up) retires the session at once; the next send reopens through the throttle. - New tests: dispose during RegisterSession, abandoned-open observer (falsified), scheduler-dispose-throws guard (DeviceSessionPool.CloseAsync), release-in-background with a shared open in flight, per-device limit scoping, CIP-close recycle (request + keep-alive + negative control). Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -172,6 +172,16 @@ The driver has two interchangeable wire transports, selected by one `DriverConfi
|
||||
two types into one value.
|
||||
- **Forward Open throttle:** at most one attempt in flight, at least 1 s between starts, bounded by the
|
||||
open budget.
|
||||
- **A target-closed CIP connection is recycled at once (#566).** When a connected reply says the controller
|
||||
no longer holds the class-3 connection while TCP stays up — general status `0x01` with extended `0x0107`
|
||||
(target connection not found) or `0x0203` (connection timed out), e.g. after a controller restart or a
|
||||
connection timeout — the session is closed (UnRegisterSession; no Forward Close, there is nothing to close)
|
||||
and the next request reopens through the throttle. The request that got the reply fails
|
||||
`BadCommunicationError` (transport `BadConnection`); a keep-alive that gets it recycles the connection
|
||||
before any request fails. Every other status — tag-level errors, other `0x01` extended codes — is left to
|
||||
the request. ⚠️ RESIDUAL: which of the two codes a real Logix controller returns for a forgotten
|
||||
connection (and whether it answers at all rather than dropping TCP) is unobserved; the check is correct
|
||||
whichever it does — a silent target still faults the session through the exchange timeout.
|
||||
- `ConnectionSize` / `Timeout` / `AllowPacking` are honoured per pooled connection, and the **first**
|
||||
driver/device to open a given device key wins — including a Test Connect probe on a fused `admin,driver`
|
||||
node (its connection carries the probe timeout). A later opener with different options is ignored and
|
||||
|
||||
Reference in New Issue
Block a user