Drain runtime commits from Economy server
This commit is contained in:
parent
5b60965dd7
commit
9fbc77e4e9
4 changed files with 76 additions and 9 deletions
Binary file not shown.
|
|
@ -129,8 +129,16 @@ catalog reader. It also proves runtime commit envelopes for settings and run
|
|||
zone/entity snapshots can be queued, applied through `Aetheria.State`, and
|
||||
cleared.
|
||||
|
||||
`Aetheria.State.ApplyPending` is the bounded local applicator for queued Unity
|
||||
runtime commits:
|
||||
`Economy.Server` opens the CultMesh state host, applies pending runtime commits
|
||||
on startup, and polls for new pending commits while running. For a bounded
|
||||
one-shot drain without leaving the host running:
|
||||
|
||||
```powershell
|
||||
dotnet run --project .\Economy.Server\Economy.Server.csproj -- --apply-pending-once
|
||||
```
|
||||
|
||||
`Aetheria.State.ApplyPending` is the smaller local operator applicator for
|
||||
queued Unity runtime commits when the server host is not being used:
|
||||
|
||||
```powershell
|
||||
dotnet run --project .\Aetheria.State.ApplyPending\Aetheria.State.ApplyPending.csproj -- .
|
||||
|
|
|
|||
|
|
@ -16,10 +16,17 @@ internal static class Program
|
|||
startServer: true).ConfigureAwait(false);
|
||||
|
||||
await EnsureWorldDocumentAsync(node).ConfigureAwait(false);
|
||||
await ApplyPendingRuntimeCommitsAsync(node).ConfigureAwait(false);
|
||||
await node.FlushAsync().ConfigureAwait(false);
|
||||
|
||||
if (HasFlag(args, "--apply-pending-once"))
|
||||
{
|
||||
Console.WriteLine("Aetheria pending runtime commit drain completed.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Aetheria CultMesh state host is running. Press Ctrl+C to stop.");
|
||||
await WaitForShutdownAsync().ConfigureAwait(false);
|
||||
await RunUntilShutdownAsync(node, PendingInterval(args)).ConfigureAwait(false);
|
||||
|
||||
Console.WriteLine("Aetheria CultMesh state host stopping.");
|
||||
}
|
||||
|
|
@ -59,7 +66,24 @@ internal static class Program
|
|||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static Task WaitForShutdownAsync()
|
||||
private static async Task ApplyPendingRuntimeCommitsAsync(AetheriaStateNode node)
|
||||
{
|
||||
var report = await AetheriaRuntimeCommitLogApplier.ApplyPendingAsync(node).ConfigureAwait(false);
|
||||
if (report.AppliedPaths.Length == 0)
|
||||
{
|
||||
Console.WriteLine("No pending Aetheria runtime commits.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine(
|
||||
"Applied pending Aetheria runtime commits: " +
|
||||
$"settings={report.AppliedPlayerSettings}, " +
|
||||
$"loadouts={report.AppliedLoadoutTemplates}, " +
|
||||
$"runs={report.AppliedRunCheckpoints}, " +
|
||||
$"files={report.AppliedPaths.Length}");
|
||||
}
|
||||
|
||||
private static async Task RunUntilShutdownAsync(AetheriaStateNode node, TimeSpan pendingInterval)
|
||||
{
|
||||
var stopped = new TaskCompletionSource<object?>();
|
||||
Console.CancelKeyPress += (_, eventArgs) =>
|
||||
|
|
@ -68,6 +92,34 @@ internal static class Program
|
|||
stopped.TrySetResult(null);
|
||||
};
|
||||
|
||||
return stopped.Task;
|
||||
while (!stopped.Task.IsCompleted)
|
||||
{
|
||||
var delay = Task.Delay(pendingInterval);
|
||||
var completed = await Task.WhenAny(stopped.Task, delay).ConfigureAwait(false);
|
||||
if (completed == stopped.Task)
|
||||
break;
|
||||
|
||||
await ApplyPendingRuntimeCommitsAsync(node).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeSpan PendingInterval(IReadOnlyList<string> args)
|
||||
{
|
||||
for (var i = 0; i < args.Count - 1; i++)
|
||||
{
|
||||
if (string.Equals(args[i], "--pending-interval-ms", StringComparison.OrdinalIgnoreCase) &&
|
||||
int.TryParse(args[i + 1], out var milliseconds) &&
|
||||
milliseconds > 0)
|
||||
{
|
||||
return TimeSpan.FromMilliseconds(milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
return TimeSpan.FromSeconds(5);
|
||||
}
|
||||
|
||||
private static bool HasFlag(IReadOnlyList<string> args, string flag)
|
||||
{
|
||||
return args.Any(arg => string.Equals(arg, flag, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,9 +41,10 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
|
|||
files, and generated keyboard layout caches no longer write bespoke durable files. The
|
||||
legacy
|
||||
`PlayerSettings` runtime object is no longer decorated as a MessagePack
|
||||
persistence shape. `Aetheria.State.ApplyPending` is the repo-local applicator
|
||||
entrypoint for draining `aetheria-world.cc.pending` into canonical typed state
|
||||
until that worker is hosted as a daemon/CultMesh organ.
|
||||
persistence shape. `Economy.Server` now drains `aetheria-world.cc.pending`
|
||||
into canonical typed state on startup and on a daemon polling loop while
|
||||
hosting the CultMesh state node. `Aetheria.State.ApplyPending` remains a
|
||||
bounded local operator applicator.
|
||||
- Shared domain state is still partly built around `DatabaseEntry`, GUID
|
||||
identity, MessagePack attributes, and static cache references. Newtonsoft,
|
||||
JsonKnownTypes, RethinkDB, LiteNetLib client transport, and the broken
|
||||
|
|
@ -117,7 +118,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
|
|||
`ActionGameManager` binds the typed runtime item catalog projected from
|
||||
`aetheria-world.cc`. MessagePack catalog construction no longer grabs global
|
||||
`DatabaseLinkBase` authority.
|
||||
- `Economy.Server` now starts the modern `Aetheria.State` CultMesh node and no
|
||||
- `Economy.Server` now starts the modern `Aetheria.State` CultMesh node, drains
|
||||
pending Unity runtime commits through the typed state applicator, and no
|
||||
longer owns RethinkDB/LiteNetLib state.
|
||||
- `Aetheria.State.Import` writes a typed quarantine manifest and migration
|
||||
ledger for the legacy catalog files. It also raw-decodes stable old
|
||||
|
|
@ -170,6 +172,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
|
|||
successfully applied command files by default. It is an operational bridge,
|
||||
not a second state owner; the applicator delegates all writes to
|
||||
`AetheriaStateNode`.
|
||||
- `Economy.Server` hosts the CultMesh state node and now owns the long-running
|
||||
pending runtime commit drain loop. `--apply-pending-once` runs the same drain
|
||||
path once for smoke/operator use without keeping the process alive.
|
||||
- `AetheriaCatalogSurfaceProjector` now emits the first provider-owned Eve
|
||||
surface from typed catalog state. The importer materializes a
|
||||
`gamecult.eve.surface.v1` catalog operator document at
|
||||
|
|
@ -530,6 +535,8 @@ First Aetheria surfaces to publish:
|
|||
documents.
|
||||
- Done: add `Aetheria.State.ApplyPending` as a bounded local applicator for
|
||||
queued runtime commits until the drain loop is hosted as a daemon.
|
||||
- Done: move the pending runtime commit drain into `Economy.Server` startup
|
||||
and daemon polling, with `--apply-pending-once` for bounded operation.
|
||||
- Done: stop legacy catalog pull/read paths from writing entries back to
|
||||
their source backing store.
|
||||
- Done: delete legacy catalog backing-store write/realtime APIs.
|
||||
|
|
|
|||
Loading…
Reference in a new issue