Skip to content

Commit 41786ff

Browse files
committed
Merge branch 'main' of https://github.com/qualabs/moq into feat/observability
2 parents 2f7a19f + 54755cd commit 41786ff

File tree

100 files changed

+702
-97
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+702
-97
lines changed

bun.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deno.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev/throttle

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/bin/bash
2+
#
3+
# Network throttle for local development (macOS)
4+
# Simulates a constrained network for QUIC testing.
5+
# Runs until Ctrl+C, then restores original settings.
6+
7+
set -e
8+
9+
# Hard-coded profile: 2Mbps, 50ms delay, 100 packet queue
10+
BANDWIDTH="2Mbit"
11+
DELAY="50ms"
12+
QUEUE="100"
13+
14+
PIPE_NUM=1
15+
PF_ANCHOR="moq-throttle"
16+
PF_CONF="/etc/pf.conf"
17+
PF_BACKUP="/tmp/pf.conf.backup"
18+
19+
# State tracking
20+
PF_WAS_ENABLED=""
21+
CLEANUP_DONE=""
22+
23+
capture_pf_state() {
24+
if sudo pfctl -s info 2>/dev/null | grep -q "Status: Enabled"; then
25+
PF_WAS_ENABLED="yes"
26+
else
27+
PF_WAS_ENABLED="no"
28+
fi
29+
}
30+
31+
cleanup() {
32+
local exit_code=$?
33+
34+
# Guard against running cleanup multiple times
35+
[ -n "$CLEANUP_DONE" ] && return
36+
CLEANUP_DONE="yes"
37+
38+
echo ""
39+
echo "Stopping network throttle..."
40+
41+
# Flush anchor rules
42+
sudo pfctl -a "$PF_ANCHOR" -F all 2>/dev/null || true
43+
44+
# Delete dummynet pipe
45+
sudo dnctl pipe $PIPE_NUM delete 2>/dev/null || true
46+
47+
# Restore original PF config
48+
if [ -f "$PF_BACKUP" ]; then
49+
sudo cp "$PF_BACKUP" "$PF_CONF"
50+
sudo pfctl -f "$PF_CONF" 2>/dev/null || true
51+
sudo rm "$PF_BACKUP"
52+
fi
53+
54+
# Restore PF enabled/disabled state (only disable if we enabled it)
55+
if [ "$PF_WAS_ENABLED" = "no" ]; then
56+
sudo pfctl -d 2>/dev/null || true
57+
fi
58+
59+
echo "Throttling disabled."
60+
exit "$exit_code"
61+
}
62+
63+
# Register cleanup for all exit paths
64+
trap cleanup EXIT
65+
66+
echo "Starting network throttle..."
67+
echo " Bandwidth: $BANDWIDTH"
68+
echo " Delay: $DELAY"
69+
echo " Queue: $QUEUE packets"
70+
71+
# Capture PF state before any changes
72+
capture_pf_state
73+
74+
# Back up pf.conf
75+
sudo cp "$PF_CONF" "$PF_BACKUP"
76+
77+
# Modify pf.conf: remove lo0 skip and add our anchor point
78+
{
79+
grep -v "set skip on lo0" "$PF_BACKUP"
80+
echo "dummynet-anchor \"$PF_ANCHOR\""
81+
echo "anchor \"$PF_ANCHOR\""
82+
} | sudo tee "$PF_CONF" > /dev/null
83+
84+
# Configure dummynet pipe
85+
sudo dnctl pipe $PIPE_NUM config bw "$BANDWIDTH" delay "$DELAY" queue "$QUEUE"
86+
87+
# Load modified pf config
88+
sudo pfctl -f "$PF_CONF" 2>/dev/null
89+
90+
# Enable PF if it wasn't already enabled
91+
if [ "$PF_WAS_ENABLED" = "no" ]; then
92+
sudo pfctl -E 2>/dev/null || true
93+
fi
94+
95+
# Add throttling rules for outbound UDP only
96+
echo "dummynet out proto udp all pipe $PIPE_NUM" | sudo pfctl -a "$PF_ANCHOR" -f -
97+
98+
echo "Throttling enabled. Press Ctrl+C to stop."
99+
echo ""
100+
101+
# Wait forever until interrupted
102+
while true; do
103+
sleep 1
104+
done

js/hang-ui/README.md

Lines changed: 61 additions & 0 deletions

js/hang-ui/package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
"license": "(MIT OR Apache-2.0)",
77
"repository": "github:moq-dev/moq",
88
"exports": {
9-
"./publish": "./src/publish.tsx",
10-
"./watch": "./src/watch.tsx",
11-
"./stats": "./src/stats.tsx"
9+
"./publish": "./src/publish/index.tsx",
10+
"./watch": "./src/watch/index.tsx"
1211
},
1312
"sideEffects": [
14-
"./src/publish.tsx",
15-
"./src/watch.tsx",
16-
"./src/stats.tsx"
13+
"./src/publish/index.tsx",
14+
"./src/watch/index.tsx"
1715
],
1816
"scripts": {
1917
"build": "bun run clean && vite build && bun ../scripts/package.ts",

js/hang-ui/src/Components/publish/CameraSourceButton.tsx renamed to js/hang-ui/src/publish/components/CameraSourceButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Show } from "solid-js";
2-
import Button from "../shared/button";
3-
import * as Icon from "../shared/icon";
2+
import Button from "../../shared/components/button/button";
3+
import * as Icon from "../../shared/components/icon/icon";
4+
import usePublishUIContext from "../hooks/use-publish-ui";
45
import MediaSourceSourceSelector from "./MediaSourceSelector";
5-
import usePublishUIContext from "./usePublishUIContext";
66

77
export default function CameraSourceButton() {
88
const context = usePublishUIContext();

js/hang-ui/src/Components/publish/FileSourceButton.tsx renamed to js/hang-ui/src/publish/components/FileSourceButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createSignal } from "solid-js";
2-
import Button from "../shared/button";
3-
import * as Icon from "../shared/icon";
4-
import usePublishUIContext from "./usePublishUIContext";
2+
import Button from "../../shared/components/button/button";
3+
import * as Icon from "../../shared/components/icon/icon";
4+
import usePublishUIContext from "../hooks/use-publish-ui";
55

66
export default function FileSourceButton() {
77
const [fileInputRef, setFileInputRef] = createSignal<HTMLInputElement | undefined>();

js/hang-ui/src/Components/publish/MediaSourceSelector.tsx renamed to js/hang-ui/src/publish/components/MediaSourceSelector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createSignal, For, Show } from "solid-js";
2-
import Button from "../shared/button";
3-
import * as Icon from "../shared/icon";
2+
import Button from "../../shared/components/button/button";
3+
import * as Icon from "../../shared/components/icon/icon";
44

55
type MediaSourceSelectorProps = {
66
sources?: MediaDeviceInfo[];

js/hang-ui/src/Components/publish/MicrophoneSourceButton.tsx renamed to js/hang-ui/src/publish/components/MicrophoneSourceButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Show } from "solid-js";
2-
import Button from "../shared/button";
3-
import * as Icon from "../shared/icon";
2+
import Button from "../../shared/components/button/button";
3+
import * as Icon from "../../shared/components/icon/icon";
4+
import usePublishUIContext from "../hooks/use-publish-ui";
45
import MediaSourceSourceSelector from "./MediaSourceSelector";
5-
import usePublishUIContext from "./usePublishUIContext";
66

77
export default function MicrophoneSourceButton() {
88
const context = usePublishUIContext();

js/hang-ui/src/Components/publish/NothingSourceButton.tsx renamed to js/hang-ui/src/publish/components/NothingSourceButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import Button from "../shared/button";
2-
import * as Icon from "../shared/icon";
3-
import usePublishUIContext from "./usePublishUIContext";
1+
import Button from "../../shared/components/button/button";
2+
import * as Icon from "../../shared/components/icon/icon";
3+
import usePublishUIContext from "../hooks/use-publish-ui";
44

55
export default function NothingSourceButton() {
66
const context = usePublishUIContext();

0 commit comments

Comments
 (0)