-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: harden media server under load #2007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
0988c6b
fix: use container-aware media admission
richiemcilroy 3e4e444
fix: harden streaming media inputs
richiemcilroy fcd1078
fix: stream large segment mux jobs
richiemcilroy d7eaffe
chore: pin media server runtime
richiemcilroy 12e3829
fix: use media server image healthcheck
richiemcilroy 06f610d
fix: preserve media health response
richiemcilroy 3f395c1
fix: reuse detected CPU capacity
richiemcilroy b6fe894
fix: cancel failed segment batches
richiemcilroy 0ee1444
fix: harden segment download cleanup
richiemcilroy e8315ea
fix: snapshot health memory metrics
richiemcilroy 6d6393f
fix: normalize segment download errors
richiemcilroy f0ee4b4
fix: use Bun for compose healthchecks
richiemcilroy 145964b
fix: make media healthchecks deterministic
richiemcilroy 4606c96
test: reset segment cancellation state
richiemcilroy a74c341
fix: reject unsafe manifest resource URLs
richiemcilroy d05fd7e
fix: scan materialized manifest protocols
richiemcilroy 8ef77fc
fix: decode DASH resource attributes
richiemcilroy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import { afterEach, describe, expect, test } from "bun:test"; | ||
| import { mkdtemp, rm, writeFile } from "node:fs/promises"; | ||
| import { tmpdir } from "node:os"; | ||
| import { join } from "node:path"; | ||
| import { | ||
| getContainerCpuLimit, | ||
| getContainerCpuUsageMicros, | ||
| } from "../../lib/container-cpu"; | ||
|
|
||
| const tempDirs: string[] = []; | ||
|
|
||
| afterEach(async () => { | ||
| await Promise.all( | ||
| tempDirs | ||
| .splice(0) | ||
| .map((path) => rm(path, { recursive: true, force: true })), | ||
| ); | ||
| }); | ||
|
|
||
| describe("container CPU metrics", () => { | ||
| test("reads a cgroup v2 CPU quota", async () => { | ||
| const dir = await mkdtemp(join(tmpdir(), "cap-container-cpu-")); | ||
| tempDirs.push(dir); | ||
| const cpuMaxPath = join(dir, "cpu.max"); | ||
| await writeFile(cpuMaxPath, "200000 100000"); | ||
|
|
||
| expect( | ||
| getContainerCpuLimit({ | ||
| cpuMaxPath, | ||
| cpuQuotaPath: join(dir, "missing-quota"), | ||
| cpuPeriodPath: join(dir, "missing-period"), | ||
| }), | ||
| ).toBe(2); | ||
| }); | ||
|
|
||
| test("reads cgroup v2 aggregate CPU usage", async () => { | ||
| const dir = await mkdtemp(join(tmpdir(), "cap-container-cpu-")); | ||
| tempDirs.push(dir); | ||
| const cpuStatPath = join(dir, "cpu.stat"); | ||
| await writeFile( | ||
| cpuStatPath, | ||
| "usage_usec 1234567\nuser_usec 1000000\nsystem_usec 234567\n", | ||
| ); | ||
|
|
||
| expect( | ||
| getContainerCpuUsageMicros({ | ||
| cpuStatPath, | ||
| cpuUsagePath: join(dir, "missing-usage"), | ||
| }), | ||
| ).toBe(1234567); | ||
| }); | ||
| }); |
53 changes: 53 additions & 0 deletions
53
apps/media-server/src/__tests__/lib/container-memory.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import { afterEach, describe, expect, test } from "bun:test"; | ||
| import { mkdtemp, rm, writeFile } from "node:fs/promises"; | ||
| import { tmpdir } from "node:os"; | ||
| import { join } from "node:path"; | ||
| import { getContainerMemoryMetrics } from "../../lib/container-memory"; | ||
|
|
||
| const tempDirs: string[] = []; | ||
|
|
||
| afterEach(async () => { | ||
| await Promise.all( | ||
| tempDirs | ||
| .splice(0) | ||
| .map((path) => rm(path, { recursive: true, force: true })), | ||
| ); | ||
| }); | ||
|
|
||
| describe("container memory metrics", () => { | ||
| test("reads cgroup usage and limit values", async () => { | ||
| const dir = await mkdtemp(join(tmpdir(), "cap-container-memory-")); | ||
| tempDirs.push(dir); | ||
| const limitPath = join(dir, "memory.max"); | ||
| const usagePath = join(dir, "memory.current"); | ||
| await writeFile(limitPath, String(1024 * 1024 * 1000)); | ||
| await writeFile(usagePath, String(1024 * 1024 * 750)); | ||
|
|
||
| const metrics = getContainerMemoryMetrics({ | ||
| limitPaths: [limitPath], | ||
| usagePaths: [usagePath], | ||
| configuredLimitMB: 0, | ||
| }); | ||
|
|
||
| expect(metrics.limitMB).toBe(1000); | ||
| expect(metrics.usageMB).toBe(750); | ||
| expect(metrics.pressure).toBe(0.75); | ||
| }); | ||
|
|
||
| test("prefers an explicit limit while retaining cgroup usage", async () => { | ||
| const dir = await mkdtemp(join(tmpdir(), "cap-container-memory-")); | ||
| tempDirs.push(dir); | ||
| const usagePath = join(dir, "memory.current"); | ||
| await writeFile(usagePath, String(1024 * 1024 * 900)); | ||
|
|
||
| const metrics = getContainerMemoryMetrics({ | ||
| limitPaths: [], | ||
| usagePaths: [usagePath], | ||
| configuredLimitMB: 1200, | ||
| }); | ||
|
|
||
| expect(metrics.limitMB).toBe(1200); | ||
| expect(metrics.usageMB).toBe(900); | ||
| expect(metrics.pressure).toBe(0.75); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.