Skip to content

feat: engine lifecycle events on the bus with Lua events.subscribe#54

Merged
tgiachi merged 3 commits into
developfrom
feature/engine-events
Jul 3, 2026
Merged

feat: engine lifecycle events on the bus with Lua events.subscribe#54
tgiachi merged 3 commits into
developfrom
feature/engine-events

Conversation

@tgiachi

@tgiachi tgiachi commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

Three pieces, one flow: the bootstrap emits lifecycle events, Lua scripts consume them by name.

Engine events (bootstrap)

EngineStartingEvent(Application), EngineStartedEvent(Application, ServiceCount, ElapsedMs), EngineStoppedEvent(Application) - published on the event bus when one is registered (guarded; the empty bootstrap is unaffected; a failing stop-publish only warns). EngineStartingEvent fires before the service loop, so only manual pre-start subscriptions see it (documented).

Lua: events.subscribe + catch-all forwarder

events.subscribe("engine_started", function(e)
    log.info("engine ready: " .. e.application .. " (" .. e.service_count .. " services)")
end)
  • Naming convention: CLR type minus the Event suffix, snake_case (EngineStartedEvent -> engine_started); payload keys snake_case. Applies to EVERY bus event.
  • LuaEventBusForwarder subscribes to the IEvent catch-all channel (already supported by the bus) and forwards to the existing Lua bridge; optional-bus ctor = no-op without a bus; a broken script never fails bus dispatch.
  • RegisterLuaEvents() wires bridge + events module + forwarder in one call; events.on stays as alias.
  • LuaEventBridge now serializes closure invocations (bus events arrive on arbitrary threads; MoonSharp is not thread-safe). Reentrancy-safe (System.Threading.Lock) for nested publishes.

Template + sample + docs

  • squidstd-host template: OnConfigLoaded/OnConfigReady examples + C# subscriptions to the engine events (scratch-built against local sources: 0 errors).
  • ScriptingLua sample: end-to-end demo - runtime output shows lua saw engine_stopped for SquidStd.Samples.ScriptingLua after shutdown.
  • Docs: Scripting.Lua README section on the naming convention, lifecycle concept caveat, tutorial output fixed.

Test Plan

  • 3 engine-event tests (ordering, payload, no-bus), 4 forwarder tests incl. a 200-parallel-publish serialization smoke, subscribe/on equivalence
  • Full suite 1031/1031; build 0 errors; docfx 0 warnings; sample runtime verified
  • No BREAKING markers

NOTE: do NOT promote to main yet - more features are landing before the next release.

tgiachi added 3 commits July 3, 2026 15:02
…case event names

Adds LuaEventBusForwarder (subscribes to the IEvent catch-all channel and
forwards every event to the Lua bridge as snake_case names with snake_case
payload keys), the events.subscribe function alongside events.on, a
RegisterLuaEvents() registration helper, and serialized closure invocation
in the bridge (bus events arrive on arbitrary threads).
…scriptions

Also demos events.subscribe in the ScriptingLua sample and documents the
snake_case event naming convention.
@tgiachi
tgiachi merged commit b9cce98 into develop Jul 3, 2026
3 checks passed

Assert.Equal("MyApp:5:true", script.Globals.Get("captured").String);

forwarder.Dispose();

Assert.Equal(200, (int)script.Globals.Get("counter").Number);

forwarder.Dispose();
Comment on lines +87 to +91
catch (Exception ex)
{
Log.ForContext<LuaEventBusForwarder>()
.Warning(ex, "Failed to forward event {EventType} to Lua", eventData.GetType().Name);
}
Comment on lines +335 to +338
catch (Exception ex)
{
logger.Warning(ex, "EngineStoppedEvent publish failed");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants