Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/homebrew/Formula/moq-gst.rb.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ class MoqGst < Formula
EOS
end

# gst-inspect-1.0 hangs at startup inside the test sandbox on a headless Mac, even for
# --version, so check the plugin links GStreamer rather than loading it. The release
# build loads it into GStreamer outside the sandbox.
test do
plugin = OS.mac? ? "libgstmoq.dylib" : "libgstmoq.so"
assert_predicate lib/"gstreamer-1.0"/plugin, :exist?
ENV["GST_REGISTRY"] = (testpath/"registry.bin").to_s
ENV["GST_PLUGIN_PATH_1_0"] = (lib/"gstreamer-1.0").to_s
ENV["GST_PLUGIN_SYSTEM_PATH_1_0"] = ""
output = shell_output("#{Formula["gstreamer"].opt_bin}/gst-inspect-1.0 moq")
assert_match (lib/"gstreamer-1.0"/plugin).to_s, output
plugin = lib/"gstreamer-1.0"/(OS.mac? ? "libgstmoq.dylib" : "libgstmoq.so")
assert_predicate plugin, :exist?
linked = plugin.dynamically_linked_libraries.map { |library| File.basename(library) }
assert linked.any? { |library| library.start_with?("libgstreamer-1.0.") }, linked.join(", ")
end
end
13 changes: 10 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ jobs:
# nextest's ignored benchmark tests and cargo's bench targets share few builds.
nightly:
name: Nightly (${{ matrix.name }})
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runner || 'ubuntu-24.04-arm' }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
# Unset keys default to the plain dev shell, the Rust cache, no perf
# sampling, no Chromium, and nextest's default profile.
# Unset keys default to the ARM runner, the plain dev shell, the Rust
# cache, no perf sampling, no Chromium, and nextest's default profile.
include:
- name: Features
recipe: rs features
Expand All @@ -72,9 +72,12 @@ jobs:
- name: Relay shard sweep
recipe: bench-shard
# Smoke-tests the capture path: exact off-CPU waits, resolved worker stacks and CPU.
# x86: on the SVE-capable ARM runner, perf's DWARF unwinding asks for the SVE VG
# register, which the kernel refuses for the software context-switches event.
- name: Relay lock-wait profile
recipe: bench-lock fanout-heavy 4
perf: true
runner: ubuntu-24.04
- name: Rust benchmark tests
recipe: gh nightly rust-test
- name: Rust bench targets
Expand Down Expand Up @@ -228,6 +231,10 @@ jobs:
run: nix develop --command just test media --media-engines ${{ matrix.engine }}
env:
MOQ_TEST_RUNS: ${{ runner.temp }}/moq-test-runs
# Playwright checks a browser's libraries with the `ldd` on PATH, which in the
# dev shell is Nix glibc's and can't see the ones `--with-deps` installed, so
# it refuses a Firefox or WebKit that launches fine.
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS: 1
- name: Preserve measurements and traces
if: ${{ failure() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ waited, in flamegraph folded format.
Linux only. A switch-out is sampled in kernel context, and 16 workers need a
larger ring buffer than the unprivileged locked-memory limit allows, so the
recipe refuses before building until `perf_event_paranoid` is -1. A recording
that still drops events is refused rather than reported.
that still drops events is refused rather than reported. On an arm64 host with
SVE, perf's DWARF unwinding requests the SVE `VG` register, which the kernel
refuses for a software event, so the recording fails to open; profile on x86.

```bash
sudo sysctl -w kernel.perf_event_paranoid=-1
Expand Down
5 changes: 2 additions & 3 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ ignore = [
# when rustcrypto/RSA publishes a constant-time fix.
"RUSTSEC-2023-0071",

# foundations (Cloudflare) pins serde_yaml 0.8 which uses yaml-rust 0.4.
"RUSTSEC-2024-0320",

# gstreamer 0.23 pulls paste (proc-macro). gstreamer 0.25 drops it but
# needs Rust 1.92, above the 1.91 workspace MSRV. Build-time only.
"RUSTSEC-2024-0436",
Expand Down Expand Up @@ -69,3 +66,5 @@ allow-wildcard-paths = true
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
# uniffi-bindgen's generator-only UniFFI fork. Unpublished, so it never ships in a crate.
allow-git = ["https://github.com/kixelated/uniffi-rs"]
3 changes: 2 additions & 1 deletion js/net/bench/forward.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* a watch coming and going over held watches and attached sessions.
*/

import { Once } from "@moq/signals";
import { announcedView } from "../src/announced.test-util";
import * as Announce from "../src/announced.ts";
import { Producer as BroadcastProducer } from "../src/broadcast.ts";
Expand All @@ -28,7 +29,7 @@ class FakeSession {
die!: () => void;

constructor() {
registerWire(this, { consume: () => new BroadcastProducer().consume() });
registerWire(this, { consume: () => new BroadcastProducer().consume(), goaway: new Once() });
this.closed = new Promise((resolve) => {
this.die = () => resolve(null);
});
Expand Down
2 changes: 1 addition & 1 deletion js/net/bench/lite-varint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const subscribe: Sample = {
const datagram: Sample = {
name: "Datagram",
encode: (w, version) => w.write(new Datagram(3n, 1_234, 1_234_567_890, new Uint8Array()).encode(version)),
decode: (r, version) => r.readAll().then((data) => Datagram.decode(data, version)),
decode: (r, version) => r.readAll().then((data) => Datagram.decode(data, version, () => true)),
};

const hop = randomHop();
Expand Down
10 changes: 1 addition & 9 deletions js/net/bench/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,5 @@
"rootDir": "..",
"noEmit": true
},
"include": [
"requests.ts",
"serve-browser.ts",
"serve-browser-entry.ts",
"serve-browser.test.ts",
"qmux.ts",
"qmux-eager.ts",
"qmux-lazy.ts"
]
"include": ["*.ts"]
}
1 change: 0 additions & 1 deletion quest/m0/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,4 @@ The historical samples locate candidates; they are not controlled benchmarks.
- [Require platform gates](/quest/m0/ci/platform-queue.md) - activate the consolidated platform checks in the main and release rulesets after the workflow lands
- [mbx on R2](/quest/m0/ci/mbx-r2.md) - Rust builds on every OS read an R2 cache that only `main` writes, escaping the 10 GB Actions cache
- [Nix cache](/quest/m0/ci/nix-cache.md) - `nix.moq.dev` on R2 replaces Cachix for CI and releases
- [Nightly workloads pass](/quest/m0/ci/nightly-green.md) - the Nightly failures found on 2026-10-16 are fixed
- [First shared FFI release](/quest/m0/ci/nightly-ffi-reuse.md) - condition: the first `moq-ffi-v*` tag that runs `Release FFI`, and a `Shipping sizes` run; verify the wrappers and size keys
1 change: 0 additions & 1 deletion quest/m0/ci/nightly-ffi-reuse.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ From the first `Shipping sizes` run:
## Related

- [Release builds link again](/quest/m0/release-link.md) - unblocks `Shipping sizes`
- [Nightly workloads pass](/quest/m0/ci/nightly-green.md) - the Nightly failures this check found
41 changes: 0 additions & 41 deletions quest/m0/ci/nightly-green.md

This file was deleted.

2 changes: 1 addition & 1 deletion rs/moq-hls/src/export/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl Broadcaster {

/// Build every rendition's init segment, so the manifest can name each by its hash. A
/// rendition whose init can't be built yet is left out of the render.
#[cfg(feature = "server")]
#[cfg_attr(not(feature = "server"), allow(dead_code))]
pub(crate) async fn build_inits(&self) {
for rendition in self.renditions.snapshot() {
if let Err(err) = rendition.init().await {
Expand Down
3 changes: 3 additions & 0 deletions rs/moq-mux/src/catalog/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ pub struct Consumer<E: CatalogExt = ()> {
inner: State<E>,
}

// One per catalog subscription, and the live variant is the working state, so boxing
// it would only add an allocation.
#[allow(clippy::large_enum_variant)]
enum State<E: CatalogExt> {
Hang(super::hang::Consumer<E>),
Msf(super::msf::Consumer<E>),
Expand Down
5 changes: 5 additions & 0 deletions rs/moq-uring/src/transport.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Adapt backend poll sessions to moq-net without changing thread affinity.
mod adapter;
pub use adapter::{Error, RecvStream, SendStream, Session};
#[cfg(feature = "quic")]
use adapter::{Grouped, GroupedSend};

#[cfg(feature = "quic")]
use crate::quic;

#[cfg(feature = "quic")]
impl Grouped for quic::web::Session {
fn send_group(&mut self, priority: i64) -> Option<quic::SendGroup> {
Some(quic::web::Session::send_group(self, priority))
Expand All @@ -20,6 +23,7 @@ impl Grouped for quic::web::Session {
}
}

#[cfg(feature = "quic")]
impl GroupedSend for quic::web::SendStream {
type Group = quic::SendGroup;

Expand All @@ -32,6 +36,7 @@ impl GroupedSend for quic::web::SendStream {
}
}

#[cfg(feature = "quic")]
impl moq_net::transport::poll::SendGroup for quic::SendGroup {
fn set_priority(&mut self, priority: i64) {
quic::SendGroup::set_priority(self, priority)
Expand Down
3 changes: 3 additions & 0 deletions rs/moq-uring/src/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ pub(crate) struct SockShared {
/// The worker, as the I/O built on this socket carries it.
owner: Owner,
/// This socket's slot in a steered reuseport group, if it is in one.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
shard: Option<moq_sock::shard::Shard>,
/// The worker's counters, held directly rather than reached through
/// `owner`, so counting a datagram is not a `Weak::upgrade`.
Expand Down Expand Up @@ -665,11 +666,13 @@ impl Socket {
}

/// The worker driving this socket, which everything built on it runs on.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
pub(crate) fn owner(&self) -> Owner {
self.shared.owner.clone()
}

/// This socket's slot in a steered reuseport group, if it is in one.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
pub(crate) fn shard(&self) -> Option<moq_sock::shard::Shard> {
self.shared.shard
}
Expand Down
4 changes: 4 additions & 0 deletions rs/moq-uring/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ pub(crate) struct Owner {
/// Held directly: a timer on a dropped worker still has to exist, since
/// the driver that owns it is torn down by the same drop that would need
/// it.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
timers: Rc<RefCell<timer::Heap>>,
}

Expand All @@ -615,18 +616,21 @@ impl Owner {
}

/// Run a `!Send` future on the worker, or drop it if the worker is gone.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
pub fn spawn(&self, future: impl Future<Output = ()> + 'static) {
if let Some(handle) = self.handle() {
handle.spawn(future);
}
}

/// A disarmed timer on the worker.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
pub fn timer(&self) -> crate::Timer {
crate::Timer::from_heap(self.timers.clone())
}

/// A timer that expires after `duration`.
#[cfg_attr(not(feature = "quic"), allow(dead_code))]
pub fn after(&self, duration: Duration) -> crate::Timer {
let mut timer = self.timer();
timer.set(Instant::now().checked_add(duration));
Expand Down
2 changes: 2 additions & 0 deletions test/lib/harness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ harness_begin() {
root="${root%/}"
[[ -n "${MOQ_TEST_RUNS:-}" ]] || root="$root/moq-test-$(id -u)"
mkdir -p "$root"
# Harnesses change directory after this, so a relative root would move under them.
root=$(CDPATH='' cd -- "$root" && pwd)
HARNESS_RUN=$(mktemp -d "$root/$name-XXXXXXXX")
# A run directory holds relay configs and generated keys, so keep it to the
# owner even where the temp root itself is world-readable.
Expand Down
12 changes: 11 additions & 1 deletion test/lib/harness.test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# Independent shells must reserve different ports even with private temp roots.
# Independent shells must reserve different ports even with private temp roots,
# and a relative MOQ_TEST_RUNS must survive a harness changing directory.
set -euo pipefail

lib=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
Expand Down Expand Up @@ -49,4 +50,13 @@ MOQ_TEST_PORTS="$scratch/ports-link" bash -euo pipefail -c '
[[ "$status" == 2 ]]
fi
' bash "$lib"
# A relative root must still name the same directory after the harness changes directory.
(cd "$scratch" && MOQ_TEST_RUNS=relative bash -euo pipefail -c '
source "$1/harness.sh"
harness_begin relative >&2
[[ "$HARNESS_RUN" == "$2"/relative/relative-* ]] || {
echo "FAIL: relative MOQ_TEST_RUNS gave run directory $HARNESS_RUN" >&2
exit 1
}
' bash "$lib" "$(cd "$scratch" && pwd)")
echo "cross-shell port reservations passed"
Loading