Deduplicate OBS source state traffic
This commit is contained in:
parent
27ae8dcb81
commit
fc5a9029ea
4
TODO.md
4
TODO.md
@ -59,6 +59,10 @@ audio and initial OBS source inventory their own soft gateway budgets, so normal
|
||||
or pathological capture cadence cannot rate-limit and disconnect the Companion
|
||||
control connection.
|
||||
|
||||
Experimental.10 deduplicates OBS source inventories and unchanged source-state
|
||||
notifications at both ends, removing the high-volume source-update feedback seen
|
||||
with large scene collections while retaining the non-disconnecting safety budget.
|
||||
|
||||
Release-blocking work remains:
|
||||
|
||||
- Package the native whisper.cpp worker as the Windows CUDA runtime, then benchmark
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef AppVersion
|
||||
#define AppVersion "0.1.0-experimental.9"
|
||||
#define AppVersion "0.1.0-experimental.10"
|
||||
#endif
|
||||
#ifndef SourceRoot
|
||||
#error SourceRoot must point at the self-contained Companion publish directory.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
param(
|
||||
[string]$Version = "0.1.0-experimental.9",
|
||||
[string]$Version = "0.1.0-experimental.10",
|
||||
[string]$BridgeVersion = "0.1.0-experimental.5"
|
||||
)
|
||||
|
||||
|
||||
@ -564,7 +564,10 @@ public sealed class CompanionRuntime : IAsyncDisposable
|
||||
ReadString(source, "display_name") ?? ReadString(source, "name") ?? "OBS source",
|
||||
ReadBoolean(source, "program_active") || ReadBoolean(source, "active"),
|
||||
ReadBoolean(source, "source_missing") || ReadBoolean(source, "missing")))
|
||||
.Where(source => Guid.TryParse(source.Uuid, out _)).ToArray();
|
||||
.Where(source => Guid.TryParse(source.Uuid, out _))
|
||||
.GroupBy(source => source.Uuid)
|
||||
.Select(group => group.Last())
|
||||
.ToArray();
|
||||
_bridgeSelectionAttached = null;
|
||||
ObsSourcesChanged?.Invoke(ObsSources);
|
||||
foreach (var source in ObsSources) await SendSourceUpdateAsync(source);
|
||||
@ -576,6 +579,8 @@ public sealed class CompanionRuntime : IAsyncDisposable
|
||||
var source = new ObsSource(ReadString(message, "source_uuid") ?? string.Empty, ReadString(message, "display_name") ?? "OBS source", ReadBoolean(message, "program_active"), ReadBoolean(message, "source_missing"));
|
||||
if (Guid.TryParse(source.Uuid, out _))
|
||||
{
|
||||
var previous = ObsSources.FirstOrDefault(item => item.Uuid == source.Uuid);
|
||||
if (previous == source) return;
|
||||
ObsSources = ObsSources.Where(item => item.Uuid != source.Uuid).Append(source).OrderBy(item => item.Name).ToArray();
|
||||
ObsSourcesChanged?.Invoke(ObsSources);
|
||||
await SendSourceUpdateAsync(source);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Version>0.1.0-experimental.9</Version>
|
||||
<Version>0.1.0-experimental.10</Version>
|
||||
<AssemblyVersion>0.1.0.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -36,6 +36,7 @@ class CompanionGateway {
|
||||
let sourceMessagesInWindow = 0;
|
||||
let audioMessagesDropped = 0;
|
||||
let sourceMessagesDropped = 0;
|
||||
const sourceStates = new Map();
|
||||
let messageChain = Promise.resolve();
|
||||
const send = (type, payload, sessionId = session?.id || null) => {
|
||||
if (socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify(envelope(type, payload, sessionId)));
|
||||
@ -65,6 +66,13 @@ class CompanionGateway {
|
||||
}
|
||||
const message = parseEnvelope(body);
|
||||
if (helloComplete && message.type === "source_update") {
|
||||
const sourceId = String(message.payload?.source_uuid || "");
|
||||
const signature = JSON.stringify(message.payload || {});
|
||||
if (sourceId && sourceStates.get(sourceId) === signature) return;
|
||||
if (sourceId) {
|
||||
sourceStates.set(sourceId, signature);
|
||||
if (sourceStates.size > 2048) sourceStates.delete(sourceStates.keys().next().value);
|
||||
}
|
||||
sourceMessagesInWindow += 1;
|
||||
if (sourceMessagesInWindow > MAX_SOURCE_MESSAGES_PER_SECOND) { sourceMessagesDropped += 1; return; }
|
||||
} else {
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"version": "0.1.0-experimental.9",
|
||||
"version": "0.1.0-experimental.10",
|
||||
"signed": false,
|
||||
"release_notes": "Prevents OBS audio and initial source-inventory bursts from rate-limiting the Companion connection by sending steady 20 ms audio frames and bounding high-volume capture traffic separately from control messages.",
|
||||
"release_notes": "Prevents OBS capture bursts from rate-limiting the Companion connection, sends steady 20 ms audio frames, and removes duplicate source-state traffic from large scene collections.",
|
||||
"installer": {
|
||||
"id": "windows-x64-installer",
|
||||
"platform": "win32",
|
||||
"architecture": "x64",
|
||||
"label": "Windows x64 per-user installer",
|
||||
"filename": "Lumi.Companion-Setup.exe",
|
||||
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.9/Lumi.Companion-Setup.exe",
|
||||
"sha256": "22bdb0f351e5b4960e2c1ae40e3bdbd8de8a8d6326b30714defb5eb202c0efcf",
|
||||
"bytes": 32039974
|
||||
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.10/Lumi.Companion-Setup.exe",
|
||||
"sha256": "8207620c1fa2a3f6371c7f5fad40f9a467146a3c44068ed6ae655ee701d98e6a",
|
||||
"bytes": 32031916
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
@ -20,9 +20,9 @@
|
||||
"architecture": "x64",
|
||||
"label": "Windows x64 self-contained",
|
||||
"filename": "Lumi.Companion-win-x64.zip",
|
||||
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.9/Lumi.Companion-win-x64.zip",
|
||||
"sha256": "70d9a780859824aa7b8a12e9f25ae8871778b83458889237f171484b2a200dbc",
|
||||
"bytes": 41757969,
|
||||
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.10/Lumi.Companion-win-x64.zip",
|
||||
"sha256": "f5a00c9bb778790caec596da475c33b3f7c8e6e67921da75e1e8e3b463bee624",
|
||||
"bytes": 41757850,
|
||||
"entrypoint": "Lumi.Companion.App.exe"
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "lumi_transcription",
|
||||
"name": "Lumi Transcription",
|
||||
"version": "0.1.0-experimental.9",
|
||||
"version": "0.1.0-experimental.10",
|
||||
"description": "Server-hosted whisper.cpp transcription for Lumi Companion and OBS closed captions.",
|
||||
"main": "index.js",
|
||||
"channel": "experimental",
|
||||
|
||||
@ -117,6 +117,7 @@ function verifyLocalhostTransportPolicy() {
|
||||
}
|
||||
|
||||
function verifyCompanionVersionOrdering() {
|
||||
assert.equal(plugin.compareVersions("0.1.0-experimental.10", "0.1.0-experimental.9"), 1);
|
||||
assert.equal(plugin.compareVersions("0.1.0-experimental.9", "0.1.0-experimental.8"), 1);
|
||||
assert.equal(plugin.compareVersions("0.1.0-experimental.8", "0.1.0-experimental.7"), 1);
|
||||
assert.equal(plugin.compareVersions("0.1.0-experimental.7", "0.1.0-experimental.6"), 1);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user