fix(ab-transport): final review I2 — wire DeviceSessionPool.Shared to the host logger
ConfigureSharedLogger had no production caller, so the pool's only diagnostics (first-wins options conflicts, scheduler/close failures) went to NullLogger. DriverFactoryBootstrap now configures it from the driver registry factory and from the AbCip/AbLegacy probe factories (admin-only nodes reach the pool only through Test Connect). Wiring tests reset the pool to a null logger first, so removing the call goes red (verified). Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -80,6 +80,9 @@ public static class DriverFactoryBootstrap
|
||||
// whole mechanism exists to prevent, and it would fail as a plant outage rather than as a
|
||||
// startup error.
|
||||
var primaryRoleSource = sp.GetRequiredService<IDriverPrimaryRoleSource>();
|
||||
// Final review I2: the native AB transport's process-wide pool logs options conflicts and close
|
||||
// failures; without this it writes to NullLogger in production.
|
||||
ConfigureAbTransportLogging(sp);
|
||||
Register(registry, loggerFactory, secretResolver, primaryRoleSource, ResolveAbCipDefaultTransport(sp),
|
||||
scriptRoot);
|
||||
return registry;
|
||||
@@ -148,8 +151,16 @@ public static class DriverFactoryBootstrap
|
||||
// driver would run. The generic factory overload keeps AbCipProbe as the implementation type, which
|
||||
// TryAddEnumerable de-dups on.
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, AbCipProbe>(
|
||||
sp => new AbCipProbe(tagFactory: null, defaultTransport: ResolveAbCipDefaultTransport(sp))));
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, AbLegacyProbe>());
|
||||
sp =>
|
||||
{
|
||||
ConfigureAbTransportLogging(sp); // admin-only nodes reach the pool through the probes alone
|
||||
return new AbCipProbe(tagFactory: null, defaultTransport: ResolveAbCipDefaultTransport(sp));
|
||||
}));
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, AbLegacyProbe>(sp =>
|
||||
{
|
||||
ConfigureAbTransportLogging(sp);
|
||||
return new AbLegacyProbe();
|
||||
}));
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, S7Probe>());
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, TwinCATProbe>());
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IDriverProbe, FocasProbe>());
|
||||
@@ -163,6 +174,19 @@ public static class DriverFactoryBootstrap
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives the native AB transport's process-wide <c>DeviceSessionPool.Shared</c> the host logger factory
|
||||
/// (final review I2). Called from every DI factory that can put the pool to use on this node (the driver
|
||||
/// registry, and the AbCip/AbLegacy probes for admin-only nodes); idempotent. A container without an
|
||||
/// <see cref="ILoggerFactory"/> leaves the pool on its null logger.
|
||||
/// </summary>
|
||||
/// <param name="sp">The service provider.</param>
|
||||
internal static void ConfigureAbTransportLogging(IServiceProvider sp)
|
||||
{
|
||||
if (sp.GetService<ILoggerFactory>() is { } loggerFactory)
|
||||
Driver.Ab.Transport.DeviceSessionPool.ConfigureSharedLogger(loggerFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The node-level AbCip default transport (<c>Drivers:AbCip:DefaultTransport</c>, bound + validated in
|
||||
/// Program.cs). A container without the options bound (test graphs) gets the compiled default.
|
||||
|
||||
Reference in New Issue
Block a user