fix(abcip): native runtime STRING capacity, mistype churn, malformed-name config error, LWORD type check; non-blocking lease release (#570, #579)
#570 - STRING: the built-in 88-byte Logix STRING holds 82 characters (LEN + DATA[82] + 2 pad), not 84; the write still sends the whole 88-byte structure and a read never decodes the pad as characters. - Mistype churn: a type refusal (CIP 0xFF/0x2107) on the existence read no longer throws from InitializeAsync, so the runtime is not disposed/re-created (and re-Forward-Opened) every poll; the driver also keeps a runtime that throws TypeMismatch from init and records the device as reachable. - Malformed tag name: a TagPath that does not parse, or a name the CIP symbolic encoder refuses (now also non-ASCII, empty member, >255-char member, unterminated subscript), is AbCipTagConfigurationException -> per-tag BadConfigurationError (named const in AbCipStatusMapper), warned once, never feeding the device backoff or health; siblings keep reading. A malformed probe tag no longer feeds the backoff either. - Micro800 BYTE/WORD/LWORD (0xD1/0xD2/0xD4) are type-checked as integers of their width: REAL/LREAL or a narrower integer over LWORD is TypeMismatch, not decoded garbage. #579 - ConnectionLease.ReleaseInBackground: one non-blocking release shape for both native AB runtimes. The AbCip runtime's Dispose no longer waits up to 2 s under the per-tag lock; the pool still registers the close synchronously so a re-create cannot overlap it. Offline soak tests (25 cycles, AbCip + AbLegacy) prove no leaked connection; FakeEipServer gains OpenConnections. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -381,12 +381,11 @@ internal sealed class NativeAbLegacyTagRuntime : IAbLegacyTagRuntime
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Releases the lease on the shared device connection (the last release closes it).</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_lease is null) return;
|
||||
// Closing does I/O (Forward Close / UnRegisterSession); never block the caller on it.
|
||||
_ = _lease.DisposeAsync().AsTask().ContinueWith(
|
||||
static t => { _ = t.Exception; }, TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
/// <summary>
|
||||
/// Releases the lease on the shared device connection (the last release closes it) without waiting:
|
||||
/// closing does I/O (Forward Close / UnRegisterSession) and the driver disposes under a per-tag lock.
|
||||
/// The same release shape as the native AbCip runtime — see <see cref="ConnectionLease.ReleaseInBackground"/>
|
||||
/// for why a re-create the next instant still cannot overlap the close (Gitea #579).
|
||||
/// </summary>
|
||||
public void Dispose() => _lease?.ReleaseInBackground();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user