114 Commits

Author SHA1 Message Date
benvin 5177d6fb72 Merge pull request 'feat(session): share the session directory between instances' (#33) from benvin/session-directory into main
ci/woodpecker/push/ci Pipeline was successful
Reviewed-on: #33
2026-09-27 11:24:31 +10:00
unkin-agent 33a5fbce9b retry building the quick connect store in the startup probe, not just reading it
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-09-26 22:56:28 +10:00
unkin-agent 6c7f76fd26 retry the quick connect startup probe, and exit non-zero when a start fails
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-09-26 22:14:14 +10:00
unkin-agent 9f4c857b23 test(session): cover the maintenance sweeps and capabilities routing
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-09-26 22:11:03 +10:00
unkin-agent af4e44173f Merge remote-tracking branch 'origin/main' into benvin/session-directory
# Conflicts:
#	.woodpecker/ci.yaml
#	Jellyfin.Server/CoreAppHost.cs
#	tests/Jellyfin.Server.Tests/HighAvailability/RedisTestServer.cs
2026-09-26 20:43:52 +10:00
unkin-agent a99ca458bf fail startup when the quick connect store is unreachable
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/pr/ci Pipeline failed
Read the configured quick connect store during InitializeServices and abort
startup, with a log line naming valkey, instead of coming up and failing on
the first request that needs the store.
2026-09-26 19:09:24 +10:00
unkin-agent 577d24d190 test(session): prove the directory and bus fall back together
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-09-26 15:12:04 +10:00
unkin-agent 611bcf2c4a fix(session): confirm routed delivery and keep playback state with the owner 2026-09-26 14:45:40 +10:00
unkin-agent e1ca272d6c fail quick connect closed on an unreachable valkey and restore the idempotent exchange
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-09-26 14:28:45 +10:00
unkin-agent 51261b0128 test(session): sample ownership after each non-owner request
ci/woodpecker/push/ci Pipeline was canceled
ci/woodpecker/pr/ci Pipeline was canceled
2026-09-25 00:01:42 +10:00
unkin-agent 9e66708d87 fix(session): tie directory ownership to the live connection
Ownership is claimed with a Lua check-and-set keyed on the instance holding
the websocket, routing prefers a live controller over a local copy, the
session list deduplicates by owner, removal is ownership-checked, undelivered
routed messages surface, single-session lookups stop scanning the keyspace and
directory writes leave the request path bounded by a timeout.
2026-09-24 23:50:01 +10:00
unkin-agent 6c54a02240 make quick connect authorize atomic and stop the fallback shadowing redis
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-09-24 23:38:35 +10:00
unkin-agent ba4d487c65 share quick connect state between instances
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Move the pending requests and authorized secrets out of process so the
initiate, authorize and exchange legs can land on different replicas.
2026-09-24 23:02:56 +10:00
unkin-agent 00d0765152 feat(session): share the session directory between instances
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/push/ci Pipeline failed
Publish every session to valkey with the instance holding it, and route a
command for a non-local session to its owner over a per-instance pub/sub
channel. Entries expire, so a dead instance leaves the directory.
2026-09-24 22:48:48 +10:00
benvin 6691b785c3 Merge pull request #32 from benvin/userdata-cache
ci/woodpecker/push/ci Pipeline was successful
fix(userdata): read user data through to the database
2026-09-21 23:13:37 +10:00
unkin-agent 1c59e6afcb perf(nextup): batch the user data reads the next episode selection makes
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Next Up walked every series in an unpaginated loop and read user data one
episode at a time, so the Home screen row cost two queries per series once the
cache was gone.

- read the played state of every candidate episode in one query
- read the versions the resume check and the last played date need in one query each
- default PrefetchedUserData on IUserBaseItemComparer so plugin comparers still compile
- cover the bounded query count and the plugin comparer with tests
- share one database across the replica tests
2026-09-21 00:36:39 +10:00
unkin-agent a7919b9bac fix(userdata): read user data through to the database
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
The user data cache and the item's in-memory rows were both filled once per
replica and never invalidated, so a pod serving a playback tick read its own
stale resume position and wrote it back over the position another pod had just
saved, silently losing resume points, played state, favourites and ratings.

- drop the user item data cache
- read single and batched user data from the database on every query
- prefetch user data for in-memory sorts and filters so each stays one query
- cover the lost update against real PostgreSQL with two manager instances
2026-09-20 23:51:29 +10:00
unkin-agent face8ac653 fix(api): normalise the Next Up cutoff to UTC
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
The query-string cutoff binds as DateTimeKind.Unspecified, which Npgsql
refuses to write to timestamp with time zone, so /Shows/NextUp 500s.
2026-09-20 23:47:23 +10:00
unkin-agent b77702c851 merge: resolve CoreAppHost conflict with main, drop dead redisConnectionString local
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-09-13 14:48:26 +10:00
benvin 2370787471 Merge pull request 'fix(db): collapse presentation-key groups without min(uuid)' (#10) from benvin/fix-guid-aggregate-pg into main
ci/woodpecker/push/ci Pipeline was successful
Reviewed-on: #10
2026-09-13 14:25:19 +10:00
benvin a652d718ca Merge pull request 'fix(ha): read transcode store config from the variable form deployments set' (#9) from benvin/ha-config-wiring into main
ci/woodpecker/push/ci Pipeline was canceled
Reviewed-on: #9
2026-09-13 14:24:11 +10:00
unkin-agent 91655fcb0a fix(ha): gate library tasks on the scan leader by default
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Jellyfin:ScanLeader:Enabled defaults to false and nothing sets it, so
leader election never runs and every replica executes the timer-driven
library tasks concurrently - the exact behaviour the lease prevents.

- Enable gating by default when a Redis connection string is configured
- Honour an explicit Enabled setting either way
- Carry the effective decision onto the bound options the task worker reads
- Log at startup whether gating is active
- Warn when gating is enabled but no Redis connection string is configured
2026-09-13 13:19:48 +10:00
unkin-agent 6e405af1dc fix(db): collapse presentation-key groups without min(uuid)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
PostgreSQL has no min(uuid) aggregate, so every query that picked a group
representative with MIN over the item id failed with 42883: library browse,
search, Recently Added, the by-name endpoints and Upcoming.

- Pick the representative with an anti-join on (primary version, id)
- Cover the collapse with a repository test against a real PostgreSQL
2026-09-13 13:18:11 +10:00
unkin-agent 95220e2ed6 fix(ha): read transcode store config from the variable form deployments set
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
The startup configuration only reads JELLYFIN_ prefixed environment
variables, so the bare Jellyfin__TranscodeStore__* form used by the chart,
the manifests and the README is dropped and the Redis store is never
registered. Nothing logs the selected store, so the fallback is invisible.

- Read bare Jellyfin__* variables into the Jellyfin:* configuration root
- Keep an explicit JELLYFIN_ variable winning over the bare form
- Log the selected transcode session store at startup
- Ping Redis once at startup and log an unreachable store at Error
- Log endpoints only, never the connection string
2026-09-13 13:10:52 +10:00
unkin-agent 56919b9565 fix(devices): read devices and device options through to the database
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
The device cache was filled once at construction, so a token minted by one
replica was unknown to every other replica already running and a token revoked
on one replica stayed valid on the others until they restarted.

- drop the eager device and device options dictionaries
- read devices and device options from the database on every query
- push the device query filters and ordering into SQL
- open the request's database context only for the api key fallback
- cover both directions against real PostgreSQL with two manager instances
2026-09-13 13:08:47 +10:00
unkin-agent bc42ff4b28 test(db): drop a leftover test database before recreating it
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
A server handed in through JELLYFIN_TEST_POSTGRES outlives the run, so a second
run finds the databases the first one created. Also name the failures in
Jellyfin.Database.Tests.PostgreSQL the CI step steps around.
2026-09-12 21:36:09 +10:00
unkin-agent b501ba9620 test(db): run the startup migration chain against PostgreSQL in CI
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Every PostgreSQL test carries Category=RequiresDocker and the pipeline filters
that category out, so the provider production runs on was never exercised and
two upgrade-path bugs reached it in a row. Nothing covered the whole startup
sequence either - code and schema migrations interleaved the way the migration
service orders them.

- run both database stages through JellyfinMigrationService against a seeded
  library and against a fresh install
- take the server from JELLYFIN_TEST_POSTGRES when it is set, else start a
  container
- add a pipeline step that runs the PostgreSQL tests on every push and pull
  request, with the server inside the step: the kubernetes backend has no
  docker daemon, and a service container deadlocks on the workspace volume
2026-09-12 21:28:17 +10:00
unkin-agent f59ab11c43 fix(db): materialise the rating list before updating
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
MigrateRatingLevels issued an ExecuteUpdate while the SELECT DISTINCT reader
was still open on the same connection. SQLite tolerates that, Npgsql does not,
so the AppInitialisation stage aborted and every PostgreSQL instance
crash-looped on startup.

- read the distinct ratings into a list before the update loop
- cover the migration against a real PostgreSQL, with NULL and empty ratings
2026-09-12 21:00:18 +10:00
unkin-agent 65af2bcbd7 fix(db): harden the PostgreSQL upgrade against odd legacy data
- accept only the two id shapes the uuid cast parses, so misplaced hyphens
  null out instead of aborting the migration
- clear an OwnerId that already is the detached placeholder, matching the
  SQLite chain, so CleanupOrphanedExtras cannot delete the item
- recreate the placeholder item before the repoint if it is missing
- compare the migrated schema against the model, constraints included
2026-09-12 16:21:42 +10:00
unkin-agent 2e3d24cc05 fix(db): restore the PostgreSQL upgrade path
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
The v12.0 rebase replaced the PostgreSQL provider's initial migration instead of
adding to it, so an existing database kept the pre-12.0 schema while the code
migrations ran against it and startup aborted on a missing NormalizedUsername.

- restore 20260305010333_InitialPostgreSql as the baseline
- add 20260306000000_UpgradeToServer12Schema carrying it to the 12.0 model
- convert OwnerId and PrimaryVersionId to uuid with explicit casts, clear
  unparseable ids and repoint dangling owners at the placeholder item
- drop orphaned permissions and preferences before UserId becomes non-nullable
- add 20260524120336_AddUniqueNormalizedUsernameIndex after the code migration
  that fills the column in
- read an empty or unknown encoding.xml EncoderPreset as the default
- cover both paths against a real PostgreSQL and guard the migration ordering
2026-09-12 15:32:12 +10:00
Shadowghost ca90347dc2 Resolve migration routine loggers from the application container 2026-09-06 07:54:11 +02:00
Shadowghost c622a16261 Don't dispose application singletons after running a code migration 2026-09-05 07:37:09 +02:00
dwandw 9962fbbe2e fix: IPv6 prefixes not recognized as proxy https://github.com/jellyfin/jellyfin/issues/15710 2026-04-27 07:13:27 +00:00
Shadowghost bd70e0ca34 Upgrade to xunit v3 2026-04-19 18:41:39 +02:00
Bond_009 9e480f6efb Update to .NET 10.0 2026-01-14 18:55:47 +01:00
Bond_009 635d67d458 Revert "Use System.Net.IPNetwork"
This reverts commit 117d05d288da1d412159a29c0cb8d5c8259e48ae.
2023-11-14 21:16:33 +01:00
Bond_009 0fd36a5bf1 Fix warnings in test projects 2023-11-14 21:14:23 +01:00
Bond_009 99e0d46ad9 Use System.Net.IPNetwork 2023-11-14 21:13:51 +01:00
Patrick Barron e463dbda47 Move network configuration to MediaBrowser.Common 2023-11-12 10:24:35 -05:00
Bond-009 b16033df03 Fix fuzz projects (#10416) 2023-10-22 09:01:51 -06:00
Tim Eisele dc27d8f9cd Refactor URI overrides (#10051) 2023-10-11 00:02:37 +02:00
Cody Robibero fb8b11276d fix build 2023-09-01 09:35:57 -06:00
Shadowghost 3a91c37283 Merge branch 'master' into network-rewrite 2023-02-15 22:40:07 +01:00
Shadowghost 4eba16c672 Apply review suggestions 2023-02-15 22:34:44 +01:00
Bond-009 6fb2fac6e4 Always run code analyzers for tests projects (#9304) 2023-02-12 10:54:55 -07:00
Zoltan Csizmadia e0519189b2 Use Directory.Packages.props (#9135)
Co-authored-by: Zoltan Csizmadia <CsizmadiaZ@valassis.com>
2023-02-04 10:15:08 -07:00
Shadowghost 656a0bff6f Merge remote-tracking branch 'upstream/master' into network-rewrite 2023-01-19 10:09:32 +01:00
renovate[bot] e408da4651 chore(deps): update dependency microsoft.codeanalysis.bannedapianalyzers to v3.3.4 (#9117)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-18 04:16:59 -07:00
Patrick Barron 74a07f6d1c Move Middleware to Jellyfin.Api 2023-01-15 15:46:50 -05:00
Patrick Barron 663854bc1e Update test dependencies (#9094) 2023-01-14 13:15:36 -07:00