feat(runtime): WithOtOpcUaRuntimeActors extension for driver-role node startup (F19)
Mirrors WithOtOpcUaControlPlaneSingletons for the driver role. Spawns DriverHostActor + DbHealthProbeActor on the host's ActorSystem and registers both under marker keys. Host's Program.cs now calls it when the node carries the driver role, so driver-only and admin+driver deployments both auto-bootstrap the per-node actors. Integration test covers the registration round-trip via Microsoft.Extensions.Hosting + Akka.Hosting AddAkka.
This commit is contained in:
@@ -8,6 +8,7 @@ using ZB.MOM.WW.OtOpcUa.Configuration;
|
||||
using ZB.MOM.WW.OtOpcUa.ControlPlane;
|
||||
using ZB.MOM.WW.OtOpcUa.Host;
|
||||
using ZB.MOM.WW.OtOpcUa.Host.Health;
|
||||
using ZB.MOM.WW.OtOpcUa.Runtime;
|
||||
using ZB.MOM.WW.OtOpcUa.Security;
|
||||
using ZB.MOM.WW.OtOpcUa.Security.Endpoints;
|
||||
|
||||
@@ -43,10 +44,8 @@ builder.Services.AddAkka("otopcua", (ab, _) =>
|
||||
{
|
||||
if (hasAdmin)
|
||||
ab.WithOtOpcUaControlPlaneSingletons();
|
||||
// Driver-role startup (DriverHostActor spawn + child probes) is wired in F19 once a
|
||||
// RuntimeStartup contract is added — the actor itself exists (Phase 6), the registration
|
||||
// extension does not yet. Without it, driver-role nodes still join the cluster and serve
|
||||
// health/redundancy traffic but won't auto-spawn DriverHostActor.
|
||||
if (hasDriver)
|
||||
ab.WithOtOpcUaRuntimeActors();
|
||||
});
|
||||
|
||||
if (hasAdmin)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using Akka.Actor;
|
||||
using Akka.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ZB.MOM.WW.OtOpcUa.Commons.Interfaces;
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration;
|
||||
using ZB.MOM.WW.OtOpcUa.Runtime.Drivers;
|
||||
using ZB.MOM.WW.OtOpcUa.Runtime.Health;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Runtime;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public const string DriverRole = "driver";
|
||||
|
||||
public const string DriverHostActorName = "driver-host";
|
||||
public const string DbHealthProbeActorName = "db-health";
|
||||
|
||||
/// <summary>
|
||||
/// Spawns the per-node driver-role actors on the host's <see cref="ActorSystem"/>:
|
||||
/// <see cref="DriverHostActor"/> (one per node) and <see cref="DbHealthProbeActor"/>
|
||||
/// (consumed by the health endpoint + redundancy calc).
|
||||
///
|
||||
/// Mirror of <c>WithOtOpcUaControlPlaneSingletons</c> for the driver role. Both must
|
||||
/// be registered on the same <see cref="AkkaConfigurationBuilder"/> as the cluster
|
||||
/// bootstrap so the actors share the host's ActorSystem.
|
||||
///
|
||||
/// Wire from the fused Host's Program.cs when the node carries the <c>driver</c> role:
|
||||
/// <code>
|
||||
/// if (hasDriver)
|
||||
/// ab.WithOtOpcUaRuntimeActors();
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static AkkaConfigurationBuilder WithOtOpcUaRuntimeActors(this AkkaConfigurationBuilder builder)
|
||||
{
|
||||
builder.WithActors((system, registry, resolver) =>
|
||||
{
|
||||
var dbFactory = resolver.GetService<IDbContextFactory<OtOpcUaConfigDbContext>>();
|
||||
var roleInfo = resolver.GetService<IClusterRoleInfo>();
|
||||
|
||||
var dbHealth = system.ActorOf(
|
||||
DbHealthProbeActor.Props(dbFactory),
|
||||
DbHealthProbeActorName);
|
||||
registry.Register<DbHealthProbeActorKey>(dbHealth);
|
||||
|
||||
var driverHost = system.ActorOf(
|
||||
DriverHostActor.Props(dbFactory, roleInfo.LocalNode),
|
||||
DriverHostActorName);
|
||||
registry.Register<DriverHostActorKey>(driverHost);
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Marker key types used by <c>Akka.Hosting</c> to resolve runtime actors from the registry.</summary>
|
||||
public sealed class DriverHostActorKey { }
|
||||
public sealed class DbHealthProbeActorKey { }
|
||||
Reference in New Issue
Block a user