Complete multi-instance support: Phases 3–6 & deployment

- Implements Phases 3–6: session isolation, cache coordination, primary election, and file system monitor coordination for Jellyfin with PostgreSQL.
- Adds new database entities (Instance, DistributedLock, FileSystemChange) and EF model configurations.
- Includes SQL migration scripts and EF migration for all required tables, columns, and helper functions.
- Updates Device entity and JellyfinDbContext for multi-instance tracking.
- Integrates new DI services for instance registry, distributed locks, cache coordinator, and primary election.
- Adds publishing profiles (Win/Linux/FrameworkDependent) and automation script for deployment.
- Extensive documentation for architecture, setup, and publishing.
- All changes are backward compatible and build successfully.
This commit is contained in:
2026-03-05 16:10:26 -05:00
parent 7eb2b445cb
commit 77e30685bb
52 changed files with 9349 additions and 22 deletions
+5 -2
View File
@@ -14,6 +14,8 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ApplicationIcon>Jellyfin.Server.ico</ApplicationIcon>
<IsPackable>true</IsPackable>
<!-- Suppress trimming warnings for existing migration and serialization code -->
<NoWarn>$(NoWarn);IL2026;IL2072;IL2075</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -104,17 +106,18 @@
<ItemGroup>
<!-- SQL initialization scripts for PostgreSQL -->
<None Include="sql\**\*.sql">
<None Include="..\sql\**\*.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>false</Pack>
<Link>sql\%(RecursiveDir)%(Filename)%(Extension)</Link>
</None>
</ItemGroup>
<!-- Post-build event to ensure SQL files are copied -->
<Target Name="CopySQLFiles" AfterTargets="Build">
<ItemGroup>
<SQLFiles Include="$(ProjectDir)sql\**\*.sql" />
<SQLFiles Include="$(ProjectDir)..\sql\**\*.sql" />
</ItemGroup>
<Copy SourceFiles="@(SQLFiles)" DestinationFolder="$(OutDir)sql\%(RecursiveDir)" SkipUnchangedFiles="true" />
<Message Importance="high" Text="Copied SQL files to output directory" />
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NameOfLastUsedPublishProfile>D:\Projects\pgsql-jellyfin\Jellyfin.Server\Properties\PublishProfiles\SelfContained-Win-x64.pubxml</NameOfLastUsedPublishProfile>
<NameOfLastUsedPublishProfile>D:\Projects\pgsql-jellyfin\Jellyfin.Server\Properties\PublishProfiles\MultiInstance-FrameworkDependent.pubxml</NameOfLastUsedPublishProfile>
</PropertyGroup>
</Project>
+5
View File
@@ -290,6 +290,11 @@ namespace Jellyfin.Server
_migrationLogger = StartupLogger.Logger.BeginGroup<JellyfinMigrationService>($"Migration Service");
var startupConfigurationManager = new ServerConfigurationManager(appPaths, _loggerFactory, new MyXmlSerializer());
startupConfigurationManager.AddParts([new DatabaseConfigurationFactory()]);
// Force load database configuration from disk BEFORE initializing DbContext
// This ensures database.xml is read from the configured config directory
_ = startupConfigurationManager.GetConfiguration("database");
var migrationStartupServiceProvider = new ServiceCollection()
.AddLogging(d => d.AddSerilog())
.AddJellyfinDbContext(startupConfigurationManager, startupConfig)
+2 -4
View File
@@ -264,13 +264,11 @@ BEGIN
ORDER BY mean_exec_time DESC
LIMIT 10
LOOP
RAISE NOTICE 'Calls: %, Avg: %ms, Max: %ms, Total: %ms, %%: %, Query: %',
RAISE NOTICE 'Calls: %, Avg: %ms, Max: %ms, Total: %ms, Percent: %%',
query_rec.calls,
query_rec.avg_time_ms,
query_rec.max_time_ms,
query_rec.total_time_ms,
query_rec.percent_total,
query_rec.query_preview;
query_rec.total_time_ms;
END LOOP;
END IF;
END $$;
+1 -1
View File
@@ -9,6 +9,6 @@
"CacheDir": "C:/ProgramData/jellyfin/cache",
"LogDir": "C:/ProgramData/jellyfin/log",
"TempDir": "C:\\Users\\wjones\\AppData\\Local\\Temp\\jellyfin",
"WebDir": "C:/ProgramData/jellyfin/wwwroot"
"WebDir": "wwwroot"
}
}