feat: subscribe_lossy — per-consumer delivery contracts on one ring #109
Workflow file for this run
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
| name: CI | |
| on: | |
| push: | |
| branches: [master] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [master] | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # ── Basic compilation check ─────────────────────────────────────────── | |
| check: | |
| name: cargo check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check | |
| # ── Test suite (unit + integration + doc-tests) ─────────────────────── | |
| test: | |
| name: cargo test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: > | |
| cargo test --lib --tests -- | |
| --skip mpmc_stress | |
| --skip stress_1m | |
| --skip arbitrary_capacity_mpmc_stress | |
| --skip arbitrary_capacity_stress | |
| timeout-minutes: 5 | |
| - run: cargo test --doc | |
| - run: > | |
| cargo test --workspace --all-features -- | |
| --skip mpmc_stress | |
| --skip stress_1m | |
| --skip bounded_cross_thread | |
| --skip mpmc_two_publishers | |
| timeout-minutes: 5 | |
| # ── Lint with Clippy ────────────────────────────────────────────────── | |
| clippy: | |
| name: clippy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo clippy --all-targets -- -D warnings | |
| - run: cargo clippy --all-targets --all-features -- -D warnings | |
| # ── Formatting check ───────────────────────────────────────────────── | |
| fmt: | |
| name: rustfmt | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt | |
| - run: cargo fmt --all -- --check | |
| # ── MSRV verification ───────────────────────────────────────────── | |
| msrv: | |
| name: MSRV 1.94 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@1.94 | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check | |
| # ── Miri (undefined-behavior detector) ──────────────────────────────── | |
| miri: | |
| name: miri | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: miri | |
| - uses: Swatinem/rust-cache@v2 | |
| # Run single-threaded correctness tests under Miri. | |
| # Multi-threaded tests are excluded because the seqlock protocol | |
| # involves deliberate optimistic data races that Miri flags as UB | |
| # (see README "Seqlock Memory Model Question"). | |
| - run: > | |
| cargo +nightly miri test --test correctness -- --test-threads=1 | |
| --skip cross_thread | |
| --skip blocking_recv | |
| --skip stress_1m | |
| --skip bounded_publish_blocks | |
| --skip bounded_publish_batch_blocks | |
| --skip subscriber_drop_unblocks | |
| --skip subscriber_group_bounded_cross | |
| --skip bounded_cross_thread | |
| --skip mpmc_two_publishers | |
| --skip mpmc_stress | |
| --skip mpmc_blocking_recv | |
| --skip mpmc_clone | |
| --skip arbitrary_capacity_stress | |
| --skip arbitrary_capacity_bounded_cross | |
| --skip arbitrary_capacity_mpmc | |
| # ── Miri on atomic-slots (the formally sound slot implementation) ──── | |
| # | |
| # This is the gate behind the crate's soundness claim. Unlike the `miri` job | |
| # above — which runs the default volatile slots single-threaded, where the | |
| # deliberate seqlock data race is expected — this runs the atomic-slots | |
| # implementation with its multi-threaded tests, and must be completely clean. | |
| # Iteration counts scale themselves down under cfg(miri); see tests/atomic_slots.rs. | |
| miri-atomic-slots: | |
| name: miri (atomic-slots) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: miri | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: > | |
| cargo +nightly miri test --features atomic-slots | |
| --test atomic_slots --test atomic_slots_payload_sizes | |
| timeout-minutes: 30 | |
| # ── Cross-platform matrix build ────────────────────────────────────── | |
| cross-platform: | |
| name: ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check | |
| - run: > | |
| cargo test --lib --tests -- | |
| --skip mpmc_stress | |
| --skip stress_1m | |
| --skip arbitrary_capacity_mpmc_stress | |
| --skip arbitrary_capacity_stress | |
| timeout-minutes: 5 | |
| # ── WASM build (verify no_std / WASM compatibility) ────────────────── | |
| wasm: | |
| name: wasm32 check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check --target wasm32-unknown-unknown | |
| # ── Hugepages feature gate (Linux only) ────────────────────────────── | |
| hugepages: | |
| name: hugepages feature | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check --features hugepages | |
| # ── atomic-slots feature gate (formally sound slot implementation) ── | |
| atomic-slots: | |
| name: atomic-slots feature | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo check --features atomic-slots | |
| - run: cargo test --features atomic-slots --test atomic_slots --test atomic_slots_payload_sizes | |
| timeout-minutes: 5 | |
| # Run correctness tests with atomic-slots, skipping heavy stress tests | |
| # that exceed CI runner capacity in debug mode. | |
| - run: > | |
| cargo test --features atomic-slots --test correctness -- | |
| --skip mpmc_stress | |
| --skip stress_1m | |
| --skip bounded_cross_thread | |
| --skip mpmc_two_publishers | |
| timeout-minutes: 5 | |
| # ── photon-ring-async tests ──────────────────────────────────────── | |
| async-crate: | |
| name: photon-ring-async | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo test -p photon-ring-async | |
| # ── photon-ring-metrics tests ────────────────────────────────────── | |
| metrics-crate: | |
| name: photon-ring-metrics | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo test -p photon-ring-metrics | |
| # ── Publish to crates.io (only on tagged releases) ─────────────────── | |
| publish: | |
| name: publish | |
| needs: [check, test, clippy, fmt, miri, miri-atomic-slots, cross-platform, wasm, hugepages, atomic-slots, async-crate, metrics-crate] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Publish to crates.io | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| # Idempotent re-runs: tolerate an already-published version, but fail | |
| # on any other error instead of masking it with `|| true`. | |
| run: | | |
| set -euo pipefail | |
| publish() { | |
| local out | |
| if out=$(cargo publish "$@" --token "$CARGO_REGISTRY_TOKEN" 2>&1); then | |
| echo "$out" | |
| elif echo "$out" | grep -qiE 'already (exists|uploaded)'; then | |
| echo "$out" | |
| echo "==> already published, skipping" | |
| else | |
| echo "$out" | |
| return 1 | |
| fi | |
| } | |
| # Order: derive → core → async + metrics; pause for index propagation. | |
| publish -p photon-ring-derive | |
| sleep 30 | |
| publish | |
| sleep 30 | |
| publish -p photon-ring-async | |
| publish -p photon-ring-metrics |