Commit Graph

8 Commits (2445da8630588267047c846cdedd995532bc7fb8)

Author SHA1 Message Date
zijiren 2445da8630
refactor(metrics): centralize registry and lifecycle tracking (#446)
## Summary

- split Prometheus definitions into domain-owned modules backed by one
registry
- eagerly initialize every metric family and fail startup on invalid or
duplicate definitions
- add reusable RAII guards for gauges and relay durations across
cancellation, panic, and retry paths
- centralize HTTP, WebSocket, gRPC, and relay recording behind
bounded-label helpers
- enforce the 65-metric bilingual catalog from registered descriptors
- persist completed explicit-message deletion and user-ban moderation
steps
- update the pinned Rust toolchain and CI jobs to `nightly-2026-08-25`
- make the CI Clippy job fail on every Rust warning with `-D warnings`
- keep Helm configuration-validation builds visible to avoid silent-run
termination
- separate Rust caches by artifact type and let Helm reuse codegen
artifacts from the Build job
- work around the nightly global next-solver memory regression and
remove obsolete rustc recursion-limit overrides
- preserve workspace Rust flags in Docker builds while applying linker
flags to the final binary

## Compatibility

- preserve all existing metric names, HELP text, label order, and
histogram buckets
- keep route-template and bounded status/error labels
- return HTTP 500 when Prometheus exposition encoding fails
- keep the latest nightly while restoring the previous coherence-only
trait-solver behavior

## Nightly memory regression

The failed CI jobs were terminated by the runner while compiling
`synctv-api-http` (SIGTERM, exit 143). Local peak-RSS measurements for
that crate were:

| Configuration | Peak RSS |
| --- | ---: |
| `nightly-2026-08-21` | 6.62 GB |
| `nightly-2026-08-25`, global next solver | 10.76 GB |
| `nightly-2026-08-25`, `-Znext-solver=coherence` | 6.64 GB |

Rust enabled `-Znext-solver=globally` by default on nightly in
[rust-lang/rust#160619](https://github.com/rust-lang/rust/pull/160619).
The same memory blow-up is tracked in
[rust-lang/rust#161748](https://github.com/rust-lang/rust/issues/161748),
and the official tracking issue documents `-Znext-solver=coherence` as
the temporary opt-out. The workspace now applies that option in
`.cargo/config.toml`.

The Dockerfile previously set `RUSTFLAGS` for linker options, which
overrode the workspace configuration and re-enabled the global solver
inside image builds. It now uses `cargo rustc` to pass linker flags only
to the final binary, preserving the workspace solver setting for every
crate.

All rustc `#![recursion_limit = "256"]` attributes were removed. The
default limit passes with the coherence-only solver, confirming that a
higher recursion limit was unrelated to the CI termination.

## Validation

- `make build-workspace`
- `make clippy-check` (`--workspace --all-targets -- -D warnings`)
- `cargo check --locked -p synctv-api-http`
- `cargo check --locked -p synctv-api-common -p synctv-api-grpc`
- `cargo test -p synctv-api-common --lib` (655 passed, 165 Docker tests
ignored)
- `cargo test -p synctv-core metrics --lib` (9 passed)
- `make fmt-check`
- `docker build --check .`
- `make validate-helm`
- `actionlint .github/workflows/ci.yml .github/workflows/helm-ci.yml`
- `npm run validate` in `docs` (124 pages, 353 links, Astro 0
errors/warnings)
4 weeks ago
zijiren 9ebfef16e9
feat(web): support runtime UI assets (#440)
## Summary

- add a `web-ui-dynamic` feature that serves a mutable Web distribution
without compile-time embedding
- add `server.web_ui_directory` and `SYNCTV_SERVER_WEB_UI_DIRECTORY`,
with per-request disk reads, SPA fallback, security headers, and path
containment checks
- keep `web-ui` release builds embedded while allowing the same
production binary and Docker image to use a mounted runtime directory
- configure `make dev-serve` to use `synctv-web-ui/dist` and document
both modes

## Docker behavior

CI continues to build release images with `web-ui`, so embedded assets
remain the default. Mounting a distribution and setting
`SYNCTV_SERVER_WEB_UI_DIRECTORY` makes that directory authoritative at
runtime.

## Verification

- `cargo fmt --all -- --check`
- `git diff --check`
- `cargo test -p synctv-api-http --features web-ui-dynamic
http::web_ui::tests`
- `cargo test -p synctv-api-http --features web-ui http::web_ui::tests`
- `cargo check -p synctv --features web-ui-dynamic`
- `cargo check -p synctv --features web-ui`
1 month ago
zijiren 0778c2b23e
feat(rtmp): add advertised publish workflow (#439)
## Summary

- add the RTMP advertised address runtime setting and use it when
returning generated publish URLs
- generate reusable media-scoped publish sessions through the
provider-owned workflow
- preserve single-use publish keys while allowing creators to mint
replacements
- update runtime-setting documentation and generated protobuf contracts

## Verification

- cargo check -p synctv --features web-ui
- git diff --check
- end-to-end RTMP publish and playback against the embedded Web UI
1 month ago
zijiren 882cbe09bb
feat(logging): add structured transport access logs (#436)
## Summary

- add structured HTTP and gRPC access logs with request correlation,
status-aware levels, response bytes, and complete body lifecycle timing
- route diagnostic and access events through independently configurable
text or JSON outputs with non-blocking writers and dropped-line
accounting
- honor the configured IANA timezone across text, JSON, diagnostic, and
access logs with DST-aware RFC 3339 offsets
- keep HTTP metric labels bounded while logging concrete unmatched paths
without query strings
- reduce local development noise by defaulting global logs to info while
retaining component debug logs

## Behavior

- HTTP 2xx and 3xx complete at info, 4xx at warn, and 5xx or body
failures at error
- slow handlers are raised to warn; ordinary client response
cancellation remains debug
- gRPC completion waits for final trailers and records the canonical
gRPC status
- request IDs are validated, propagated in responses, and included in
mapped gRPC errors
- header latency and full response lifecycle latency are reported
separately
- log timestamps use the configured time.timezone and include a numeric
UTC offset

## Testing

- cargo test -p synctv-api-common transport_access_log --lib
- cargo test -p synctv-core logging::tests --lib
- cargo test -p synctv resource_options::tests --lib
- cargo clippy for affected crates and all targets with warnings denied
- cargo check --workspace --all-targets
- cargo fmt --all -- --check
- git diff --check
- local server smoke tests for request completion, request ID
propagation, byte counts, query omission, and Asia/Shanghai timestamps
in diagnostic and access logs
1 month ago
zijiren 63c370876d
feat(web): add client-aware playback and reproducible UI (#433)
## Summary

- add a versioned playback client profile for browser/runtime protocol,
container, codec, header, proxy, insecure-media, and P2P-loader
capabilities
- generate compatible direct and proxy resources inside each provider
and return a structured incompatibility error when route policy leaves
no viable result
- force provider proxy delivery for browser-forbidden headers, including
affected Bilibili variants, while preserving explicit direct-only
failures
- keep legacy clients compatible and isolate capability-aware playback
cache entries
- serve `/oauth2/callback` through the same Flutter SPA entry point and
keep public discovery anonymous

## Reproducible Web UI

- move Flutter acquisition/build, source configuration, asset manifests,
Brotli/gzip compression, and compile-time embedding into the independent
`synctv-web-ui` crate
- support prebuilt distributions, local projects, and Git sources pinned
to an immutable full commit, with an ignored local override
- fingerprint source, Flutter version, build arguments, dart-defines,
builder generation, output, and compression settings
- validate cached Git repository/revision/commit identity, support
offline cache reuse, and rebuild only when relevant inputs change
- pin and checksum the Flutter SDK in the Docker Web asset stage;
backend-only builds require no Flutter, Git fetch, or network
- serve embedded assets with ETags, compression negotiation, CSP, cache
policy, Origin/CORS handling, and SPA fallback outside API/media routes

## Verification

- `cargo fmt --all -- --check`
- workspace `cargo check`, test/doc-test, and all-targets Clippy with
warnings denied
- provider tests: 200 passed, 1 ignored
- OAuth core/API tests: 72 + 16 passed
- `synctv-web-ui`: 10 passed
- `synctv-api-http --features web-ui`: 12 passed
- default Git source cold build from the pinned App commit, followed by
offline hot-cache reuse in about 1.1 seconds
- `cargo check -p synctv --features web-ui` and `docker buildx build
--check .`
- real Chrome playback, P2P, OAuth/Casdoor, multi-user sync, chat,
media, playlist, upload, settings, and playback-history flows

Companion frontend PR: https://github.com/synctv-org/synctv-app/pull/52

Release pin validation:
https://github.com/synctv-org/synctv-release/pull/9
1 month ago
zijiren 9e0e0c280e
chore(dev): remove background server targets (#407)
## Summary

- remove the `dev-start` and `dev-stop` Makefile targets and related
documentation
- keep `dev-serve` as the foreground development server entry point
- make the provider smoke test own and clean up its server process
- keep `dev-down` and `dev-clean` scoped to Compose services

## Verification

- `bash -n scripts/dev-e2e-smoke.sh`
- Makefile dry runs for `dev-serve`, `dev-down`, and `dev-clean`
- `make help` target inspection
- `git diff --check`
- existing development backend health check
1 month ago
zijiren 0043ec8b2e
feat(providers): unify discovery and playback routing (#397)
## Summary

- expose server-side provider discovery and listing for media and
dynamic playlist variants
- keep provider-specific playback proxy policy inside each provider and
add meaningful prefer/only controls
- harden Emby item classification, cloud/NAS playback routing,
account-bound credentials, and unknown source-config fields
- add real Docker fixtures and end-to-end smoke coverage for Nextcloud,
Seafile, Emby, Jellyfin, OpenList, and provider playback

Related App PR: https://github.com/synctv-org/synctv-app/pull/18

## Testing

- cargo +nightly check --workspace --locked
- cargo +nightly test -p synctv-media-providers seafile::client::tests
--locked
- bash -n scripts/dev-e2e-smoke.sh
- scripts/dev-e2e-smoke.sh with real Docker services and playback URL
downloads
- git diff --check
1 month ago
zijiren233 5425eaf436 chore: replace synctv-org backend with SyncTV v1.0.0 2 months ago