fix(site-runtime): reject invalid runtime actor names at the site gate and never let ActorOf escalate to the Deployment Manager (review 2026-10-21 01/SR-C1)
An instance unique name Akka refuses as a path element (space, '#', '/', non-ASCII) made Context.ActorOf throw on the singleton's own thread; the default Restart stopped every Instance Actor on the site. DeployCompileValidator now checks the instance + script/alarm/native-source actor names with ActorPath.IsValidPathElement (the Commons ActorNameRules mirror is stricter than Akka for " ( ), pinned by a parity sweep), CreateInstanceActor catches InvalidActorNameException and every caller reports it, and the Instance Actor skips a refused child name like a compile failure.
This commit is contained in:
@@ -1943,7 +1943,8 @@ public class InstanceActor : ReceiveActor
|
||||
_healthCollector,
|
||||
_serviceProvider));
|
||||
|
||||
var actorRef = Context.ActorOf(props, $"script-{script.CanonicalName}");
|
||||
var actorRef = TryCreateChild(props, $"script-{script.CanonicalName}", "Script", script.CanonicalName);
|
||||
if (actorRef == null) continue;
|
||||
_scriptActors[script.CanonicalName] = actorRef;
|
||||
RouteChild(actorRef, TriggerRouting.ForScript(script.TriggerType, script.TriggerConfiguration));
|
||||
}
|
||||
@@ -2001,7 +2002,8 @@ public class InstanceActor : ReceiveActor
|
||||
// Per-script timeout for the alarm on-trigger script.
|
||||
onTriggerTimeoutSeconds));
|
||||
|
||||
var actorRef = Context.ActorOf(props, $"alarm-{alarm.CanonicalName}");
|
||||
var actorRef = TryCreateChild(props, $"alarm-{alarm.CanonicalName}", "Alarm", alarm.CanonicalName);
|
||||
if (actorRef == null) continue;
|
||||
_alarmActors[alarm.CanonicalName] = actorRef;
|
||||
_alarmPriorities[alarm.CanonicalName] = alarm.PriorityLevel;
|
||||
_alarmMesReportable[alarm.CanonicalName] = alarm.IsMesReportable;
|
||||
@@ -2034,7 +2036,9 @@ public class InstanceActor : ReceiveActor
|
||||
nativeKind,
|
||||
_serviceProvider));
|
||||
|
||||
var actorRef = Context.ActorOf(props, $"native-alarm-{nativeSource.CanonicalName}");
|
||||
var actorRef = TryCreateChild(
|
||||
props, $"native-alarm-{nativeSource.CanonicalName}", "Native alarm source", nativeSource.CanonicalName);
|
||||
if (actorRef == null) continue;
|
||||
_nativeAlarmActors[nativeSource.CanonicalName] = actorRef;
|
||||
// Same kind handed to the NativeAlarmActor — used to stamp the
|
||||
// (cosmetic) kind badge on placeholder rows for quiet bindings.
|
||||
@@ -2046,6 +2050,31 @@ public class InstanceActor : ReceiveActor
|
||||
_instanceUniqueName, _scriptActors.Count, _alarmActors.Count, _nativeAlarmActors.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates one child actor, or returns <see langword="null"/> when Akka refuses its name
|
||||
/// (review 2026-10-21 01/SR-C1). The site deploy gate rejects such names before anything is
|
||||
/// applied, so this only fires for a config stored before the gate checked names (boot load,
|
||||
/// enable, self-heal) — and there it is handled like a compile failure: the offending child is
|
||||
/// logged and skipped, the rest of the instance runs. It used to throw out of
|
||||
/// <see cref="PreStart"/> and fail the whole instance.
|
||||
/// </summary>
|
||||
private IActorRef? TryCreateChild(Props props, string actorName, string kind, string canonicalName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Context.ActorOf(props, actorName);
|
||||
}
|
||||
// Only a name Akka refuses OUTRIGHT is skipped. A duplicate canonical name (also an
|
||||
// InvalidActorNameException, "not unique") keeps failing PreStart as it always has.
|
||||
catch (InvalidActorNameException ex) when (!ActorPath.IsValidPathElement(actorName))
|
||||
{
|
||||
_logger.LogError(ex,
|
||||
"{Kind} '{Name}' on instance '{Instance}' skipped — its name cannot be used as a runtime actor name",
|
||||
kind, canonicalName, _instanceUniqueName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a bound connection's protocol to the native alarm kind stamped on
|
||||
/// emitted events. MxAccess Gateway connections yield
|
||||
|
||||
Reference in New Issue
Block a user