From 475a29b10dc4290cc5374e0da08224e1a0fe5513 Mon Sep 17 00:00:00 2001 From: Glax Date: Thu, 15 May 2025 15:13:53 +0200 Subject: [PATCH] Attach Entities to Jobs --- API/Controllers/JobController.cs | 1 + API/Controllers/LibraryConnectorController.cs | 3 +- API/Controllers/LocalLibrariesController.cs | 1 + API/Controllers/MangaConnectorController.cs | 2 +- API/Controllers/MangaController.cs | 1 + .../NotificationConnectorController.cs | 4 +- API/Controllers/QueryController.cs | 1 + API/Controllers/SearchController.cs | 1 + API/Controllers/SettingsController.cs | 1 + API/Program.cs | 64 ++++++++++++------- API/Schema/Contexts/LibraryContext.cs | 18 ++++++ API/Schema/Contexts/NotificationsContext.cs | 10 +++ API/Schema/{ => Contexts}/PgsqlContext.cs | 32 ++++++---- .../Jobs/DownloadAvailableChaptersJob.cs | 2 + API/Schema/Jobs/DownloadMangaCoverJob.cs | 2 + API/Schema/Jobs/DownloadSingleChapterJob.cs | 2 + API/Schema/Jobs/Job.cs | 5 +- API/Schema/Jobs/MoveFileOrFolderJob.cs | 1 + API/Schema/Jobs/MoveMangaLibraryJob.cs | 2 + API/Schema/Jobs/RetrieveChaptersJob.cs | 3 +- API/Schema/Jobs/UpdateFilesDownloadedJob.cs | 2 + API/Schema/MangaConnectors/Global.cs | 4 +- API/Tranga.cs | 27 ++++---- 23 files changed, 132 insertions(+), 57 deletions(-) create mode 100644 API/Schema/Contexts/LibraryContext.cs create mode 100644 API/Schema/Contexts/NotificationsContext.cs rename API/Schema/{ => Contexts}/PgsqlContext.cs (90%) diff --git a/API/Controllers/JobController.cs b/API/Controllers/JobController.cs index 97714b0..a4011ea 100644 --- a/API/Controllers/JobController.cs +++ b/API/Controllers/JobController.cs @@ -1,5 +1,6 @@ using API.APIEndpointRecords; using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using Asp.Versioning; using log4net; diff --git a/API/Controllers/LibraryConnectorController.cs b/API/Controllers/LibraryConnectorController.cs index 343462c..0db5748 100644 --- a/API/Controllers/LibraryConnectorController.cs +++ b/API/Controllers/LibraryConnectorController.cs @@ -1,4 +1,5 @@ using API.Schema; +using API.Schema.Contexts; using API.Schema.LibraryConnectors; using Asp.Versioning; using log4net; @@ -10,7 +11,7 @@ namespace API.Controllers; [ApiVersion(2)] [ApiController] [Route("v{v:apiVersion}/[controller]")] -public class LibraryConnectorController(PgsqlContext context, ILog Log) : Controller +public class LibraryConnectorController(LibraryContext context, ILog Log) : Controller { /// /// Gets all configured ToLibrary-Connectors diff --git a/API/Controllers/LocalLibrariesController.cs b/API/Controllers/LocalLibrariesController.cs index 004fa6d..9f09118 100644 --- a/API/Controllers/LocalLibrariesController.cs +++ b/API/Controllers/LocalLibrariesController.cs @@ -1,5 +1,6 @@ using API.APIEndpointRecords; using API.Schema; +using API.Schema.Contexts; using Asp.Versioning; using log4net; using Microsoft.AspNetCore.Mvc; diff --git a/API/Controllers/MangaConnectorController.cs b/API/Controllers/MangaConnectorController.cs index 91c7f14..095ee59 100644 --- a/API/Controllers/MangaConnectorController.cs +++ b/API/Controllers/MangaConnectorController.cs @@ -1,4 +1,4 @@ -using API.Schema; +using API.Schema.Contexts; using API.Schema.MangaConnectors; using Asp.Versioning; using log4net; diff --git a/API/Controllers/MangaController.cs b/API/Controllers/MangaController.cs index 07a4065..6098d3a 100644 --- a/API/Controllers/MangaController.cs +++ b/API/Controllers/MangaController.cs @@ -1,4 +1,5 @@ using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using Asp.Versioning; using log4net; diff --git a/API/Controllers/NotificationConnectorController.cs b/API/Controllers/NotificationConnectorController.cs index 66ef992..a242e68 100644 --- a/API/Controllers/NotificationConnectorController.cs +++ b/API/Controllers/NotificationConnectorController.cs @@ -1,6 +1,6 @@ using System.Text; using API.APIEndpointRecords; -using API.Schema; +using API.Schema.Contexts; using API.Schema.NotificationConnectors; using Asp.Versioning; using log4net; @@ -13,7 +13,7 @@ namespace API.Controllers; [ApiController] [Produces("application/json")] [Route("v{v:apiVersion}/[controller]")] -public class NotificationConnectorController(PgsqlContext context, ILog Log) : Controller +public class NotificationConnectorController(NotificationsContext context, ILog Log) : Controller { /// /// Gets all configured Notification-Connectors diff --git a/API/Controllers/QueryController.cs b/API/Controllers/QueryController.cs index 8877a8d..f4d603f 100644 --- a/API/Controllers/QueryController.cs +++ b/API/Controllers/QueryController.cs @@ -1,4 +1,5 @@ using API.Schema; +using API.Schema.Contexts; using Asp.Versioning; using log4net; using Microsoft.AspNetCore.Mvc; diff --git a/API/Controllers/SearchController.cs b/API/Controllers/SearchController.cs index 8ba0e45..86daa71 100644 --- a/API/Controllers/SearchController.cs +++ b/API/Controllers/SearchController.cs @@ -1,4 +1,5 @@ using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using API.Schema.MangaConnectors; using Asp.Versioning; diff --git a/API/Controllers/SettingsController.cs b/API/Controllers/SettingsController.cs index 04da6a5..f6cbd05 100644 --- a/API/Controllers/SettingsController.cs +++ b/API/Controllers/SettingsController.cs @@ -1,5 +1,6 @@ using API.MangaDownloadClients; using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using Asp.Versioning; using log4net; diff --git a/API/Program.cs b/API/Program.cs index 0670a65..e9f59a5 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -1,7 +1,7 @@ using System.Reflection; -using System.Text.Json.Serialization; using API; using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using API.Schema.MangaConnectors; using Asp.Versioning; @@ -55,11 +55,17 @@ builder.Services.AddSwaggerGen(opt => }); builder.Services.ConfigureOptions(); +string ConnectionString = $"Host={Environment.GetEnvironmentVariable("POSTGRES_HOST") ?? "localhost:5432"}; " + + $"Database={Environment.GetEnvironmentVariable("POSTGRES_DB") ?? "postgres"}; " + + $"Username={Environment.GetEnvironmentVariable("POSTGRES_USER") ?? "postgres"}; " + + $"Password={Environment.GetEnvironmentVariable("POSTGRES_PASSWORD") ?? "postgres"}"; + builder.Services.AddDbContext(options => - options.UseNpgsql($"Host={Environment.GetEnvironmentVariable("POSTGRES_HOST")??"localhost:5432"}; " + - $"Database={Environment.GetEnvironmentVariable("POSTGRES_DB")??"postgres"}; " + - $"Username={Environment.GetEnvironmentVariable("POSTGRES_USER")??"postgres"}; " + - $"Password={Environment.GetEnvironmentVariable("POSTGRES_PASSWORD")??"postgres"}")); + options.UseNpgsql(ConnectionString)); +builder.Services.AddDbContext(options => + options.UseNpgsql(ConnectionString)); +builder.Services.AddDbContext(options => + options.UseNpgsql(ConnectionString)); builder.Services.AddControllers(options => { @@ -99,30 +105,42 @@ app.UseHttpsRedirection(); app.UseMiddleware(); -using (var scope = app.Services.CreateScope()) +using (IServiceScope scope = app.Services.CreateScope()) { - var db = scope.ServiceProvider.GetRequiredService(); - db.Database.Migrate(); -} - -using (var scope = app.Services.CreateScope()) -{ - PgsqlContext context = scope.ServiceProvider.GetService()!; + PgsqlContext context = scope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); MangaConnector[] connectors = - [ - new MangaDex(), - new Global(scope.ServiceProvider.GetService()!) - ]; + [ + new MangaDex(), + new Global(scope.ServiceProvider.GetService()!) + ]; MangaConnector[] newConnectors = connectors.Where(c => !context.MangaConnectors.Contains(c)).ToArray(); context.MangaConnectors.AddRange(newConnectors); - - context.Jobs.AddRange(context.Mangas.AsEnumerable().Select(m => new UpdateFilesDownloadedJob(m, 0))); - - context.Jobs.RemoveRange(context.Jobs.Where(j => j.state == JobState.Completed && j.RecurrenceMs < 1)); - if (!context.LocalLibraries.Any()) - context.LocalLibraries.Add(new LocalLibrary(TrangaSettings.downloadLocation, "Default ToLibrary")); + context.LocalLibraries.Add(new LocalLibrary(TrangaSettings.downloadLocation, "Default Library")); + + context.Jobs.AddRange(context.Jobs.Where(j => j.JobType == JobType.DownloadAvailableChaptersJob) + .AsEnumerable() + .Select(dacj => + { + DownloadAvailableChaptersJob? j = dacj as DownloadAvailableChaptersJob; + return new UpdateFilesDownloadedJob(j!.Manga, 0); + })); + context.Jobs.RemoveRange(context.Jobs.Where(j => j.state == JobState.Completed && j.RecurrenceMs < 1)); + foreach (Job job in context.Jobs.Where(j => j.state == JobState.Running)) + { + job.state = JobState.FirstExecution; + job.LastExecution = DateTime.UnixEpoch; + } + + context.SaveChanges(); +} + +using (IServiceScope scope = app.Services.CreateScope()) +{ + NotificationsContext context = scope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); string[] emojis = { "(•‿•)", "(づ \u25d5‿\u25d5 )づ", "( \u02d8\u25bd\u02d8)っ\u2668", "=\uff3e\u25cf \u22cf \u25cf\uff3e=", "(ΦωΦ)", "(\u272a\u3268\u272a)", "( ノ・o・ )ノ", "(〜^\u2207^ )〜", "~(\u2267ω\u2266)~","૮ \u00b4• ﻌ \u00b4• ა", "(\u02c3ᆺ\u02c2)", "(=\ud83d\udf66 \u0f1d \ud83d\udf66=)"}; context.Notifications.Add(new Notification("Tranga Started", emojis[Random.Shared.Next(0, emojis.Length - 1)], NotificationUrgency.High)); diff --git a/API/Schema/Contexts/LibraryContext.cs b/API/Schema/Contexts/LibraryContext.cs new file mode 100644 index 0000000..8d13ef6 --- /dev/null +++ b/API/Schema/Contexts/LibraryContext.cs @@ -0,0 +1,18 @@ +using API.Schema.LibraryConnectors; +using Microsoft.EntityFrameworkCore; + +namespace API.Schema.Contexts; + +public class LibraryContext(DbContextOptions options) : DbContext(options) +{ + public DbSet LibraryConnectors { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //LibraryConnector Types + modelBuilder.Entity() + .HasDiscriminator(l => l.LibraryType) + .HasValue(LibraryType.Komga) + .HasValue(LibraryType.Kavita); + } +} \ No newline at end of file diff --git a/API/Schema/Contexts/NotificationsContext.cs b/API/Schema/Contexts/NotificationsContext.cs new file mode 100644 index 0000000..26f5699 --- /dev/null +++ b/API/Schema/Contexts/NotificationsContext.cs @@ -0,0 +1,10 @@ +using API.Schema.NotificationConnectors; +using Microsoft.EntityFrameworkCore; + +namespace API.Schema.Contexts; + +public class NotificationsContext(DbContextOptions options) : DbContext(options) +{ + public DbSet NotificationConnectors { get; set; } + public DbSet Notifications { get; set; } +} \ No newline at end of file diff --git a/API/Schema/PgsqlContext.cs b/API/Schema/Contexts/PgsqlContext.cs similarity index 90% rename from API/Schema/PgsqlContext.cs rename to API/Schema/Contexts/PgsqlContext.cs index c7cbbb9..fc1f1f9 100644 --- a/API/Schema/PgsqlContext.cs +++ b/API/Schema/Contexts/PgsqlContext.cs @@ -1,10 +1,9 @@ using API.Schema.Jobs; using API.Schema.LibraryConnectors; using API.Schema.MangaConnectors; -using API.Schema.NotificationConnectors; using Microsoft.EntityFrameworkCore; -namespace API.Schema; +namespace API.Schema.Contexts; public class PgsqlContext(DbContextOptions options) : DbContext(options) { @@ -15,9 +14,6 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op public DbSet Chapters { get; set; } public DbSet Authors { get; set; } public DbSet Tags { get; set; } - public DbSet LibraryConnectors { get; set; } - public DbSet NotificationConnectors { get; set; } - public DbSet Notifications { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -109,7 +105,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .HasMany(root => root.DependsOnJobs) .WithMany(); modelBuilder.Entity() - .Navigation(root => root.DependsOnJobs) + .Navigation(j => j.DependsOnJobs) .AutoInclude(false); //MangaConnector Types @@ -138,14 +134,23 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op modelBuilder.Entity() .Navigation(c => c.ParentManga) .AutoInclude(); + modelBuilder.Entity() + .Navigation(m => m.Chapters) + .AutoInclude(); //Manga owns MangaAltTitles modelBuilder.Entity() .OwnsMany(m => m.AltTitles) .WithOwner(); + modelBuilder.Entity() + .Navigation(m => m.AltTitles) + .AutoInclude(); //Manga owns Links modelBuilder.Entity() .OwnsMany(m => m.Links) .WithOwner(); + modelBuilder.Entity() + .Navigation(m => m.Links) + .AutoInclude(); //Manga has many Tags associated with many Manga modelBuilder.Entity() .HasMany(m => m.MangaTags) @@ -155,6 +160,9 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op r => r.HasOne(typeof(Manga)).WithMany().HasForeignKey("MangaIds").HasPrincipalKey(nameof(Manga.MangaId)), j => j.HasKey("MangaTagIds", "MangaIds") ); + modelBuilder.Entity() + .Navigation(m => m.MangaTags) + .AutoInclude(); //Manga has many Authors associated with many Manga modelBuilder.Entity() .HasMany(m => m.Authors) @@ -164,6 +172,9 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op r => r.HasOne(typeof(Manga)).WithMany().HasForeignKey("MangaIds").HasPrincipalKey(nameof(Manga.MangaId)), j => j.HasKey("AuthorIds", "MangaIds") ); + modelBuilder.Entity() + .Navigation(m => m.Authors) + .AutoInclude(); //LocalLibrary has many Mangas modelBuilder.Entity() @@ -171,11 +182,8 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .WithOne(m => m.Library) .HasForeignKey(m => m.LibraryId) .OnDelete(DeleteBehavior.SetNull); - - //LibraryConnector Types - modelBuilder.Entity() - .HasDiscriminator(l => l.LibraryType) - .HasValue(LibraryType.Komga) - .HasValue(LibraryType.Kavita); + modelBuilder.Entity() + .Navigation(m => m.Library) + .AutoInclude(); } } \ No newline at end of file diff --git a/API/Schema/Jobs/DownloadAvailableChaptersJob.cs b/API/Schema/Jobs/DownloadAvailableChaptersJob.cs index 164ad9b..1e45cfa 100644 --- a/API/Schema/Jobs/DownloadAvailableChaptersJob.cs +++ b/API/Schema/Jobs/DownloadAvailableChaptersJob.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using API.Schema.Contexts; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -26,6 +27,7 @@ public class DownloadAvailableChaptersJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Manga); return Manga.Chapters.Select(chapter => new DownloadSingleChapterJob(chapter, this)); } } \ No newline at end of file diff --git a/API/Schema/Jobs/DownloadMangaCoverJob.cs b/API/Schema/Jobs/DownloadMangaCoverJob.cs index 4eccd68..d748fa3 100644 --- a/API/Schema/Jobs/DownloadMangaCoverJob.cs +++ b/API/Schema/Jobs/DownloadMangaCoverJob.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -27,6 +28,7 @@ public class DownloadMangaCoverJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Manga); try { Manga.CoverFileNameInCache = Manga.MangaConnector.SaveCoverImageToCache(Manga); diff --git a/API/Schema/Jobs/DownloadSingleChapterJob.cs b/API/Schema/Jobs/DownloadSingleChapterJob.cs index b26a01c..9e4f94f 100644 --- a/API/Schema/Jobs/DownloadSingleChapterJob.cs +++ b/API/Schema/Jobs/DownloadSingleChapterJob.cs @@ -2,6 +2,7 @@ using System.IO.Compression; using System.Runtime.InteropServices; using API.MangaDownloadClients; +using API.Schema.Contexts; using Newtonsoft.Json; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Jpeg; @@ -35,6 +36,7 @@ public class DownloadSingleChapterJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Chapter); string[] imageUrls = Chapter.ParentManga.MangaConnector.GetChapterImageUrls(Chapter); if (imageUrls.Length < 1) { diff --git a/API/Schema/Jobs/Job.cs b/API/Schema/Jobs/Job.cs index 7639a16..fbb36c3 100644 --- a/API/Schema/Jobs/Job.cs +++ b/API/Schema/Jobs/Job.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using API.Schema.Contexts; using log4net; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -62,14 +63,16 @@ public abstract class Job { Log.Debug($"Running job {JobId}"); using IServiceScope scope = serviceProvider.CreateScope(); - PgsqlContext context = scope.ServiceProvider.GetRequiredService(); try { + PgsqlContext context = scope.ServiceProvider.GetRequiredService(); + context.Attach(this); this.state = JobState.Running; context.SaveChanges(); Job[] newJobs = RunInternal(context).ToArray(); this.state = JobState.Completed; + context.SaveChanges(); context.Jobs.AddRange(newJobs); context.SaveChanges(); Log.Info($"Job {JobId} completed. Generated {newJobs.Length} new jobs."); diff --git a/API/Schema/Jobs/MoveFileOrFolderJob.cs b/API/Schema/Jobs/MoveFileOrFolderJob.cs index b837239..ef71104 100644 --- a/API/Schema/Jobs/MoveFileOrFolderJob.cs +++ b/API/Schema/Jobs/MoveFileOrFolderJob.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using API.Schema.Contexts; namespace API.Schema.Jobs; diff --git a/API/Schema/Jobs/MoveMangaLibraryJob.cs b/API/Schema/Jobs/MoveMangaLibraryJob.cs index 853af00..a533e9c 100644 --- a/API/Schema/Jobs/MoveMangaLibraryJob.cs +++ b/API/Schema/Jobs/MoveMangaLibraryJob.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -32,6 +33,7 @@ public class MoveMangaLibraryJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Manga); Dictionary oldPath = Manga.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath); Manga.Library = ToLibrary; try diff --git a/API/Schema/Jobs/RetrieveChaptersJob.cs b/API/Schema/Jobs/RetrieveChaptersJob.cs index d9e7b7e..a89f7c6 100644 --- a/API/Schema/Jobs/RetrieveChaptersJob.cs +++ b/API/Schema/Jobs/RetrieveChaptersJob.cs @@ -1,5 +1,5 @@ using System.ComponentModel.DataAnnotations; -using API.Schema.MangaConnectors; +using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -31,6 +31,7 @@ public class RetrieveChaptersJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Manga); // This gets all chapters that are not downloaded Chapter[] allChapters = Manga.MangaConnector.GetChapters(Manga, Language); Chapter[] newChapters = allChapters.Where(chapter => context.Chapters.Contains(chapter) == false).ToArray(); diff --git a/API/Schema/Jobs/UpdateFilesDownloadedJob.cs b/API/Schema/Jobs/UpdateFilesDownloadedJob.cs index a1e0c96..b0497ee 100644 --- a/API/Schema/Jobs/UpdateFilesDownloadedJob.cs +++ b/API/Schema/Jobs/UpdateFilesDownloadedJob.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -27,6 +28,7 @@ public class UpdateFilesDownloadedJob : Job protected override IEnumerable RunInternal(PgsqlContext context) { + context.Attach(Manga); foreach (Chapter chapter in Manga.Chapters) chapter.Downloaded = chapter.CheckDownloaded(); diff --git a/API/Schema/MangaConnectors/Global.cs b/API/Schema/MangaConnectors/Global.cs index c4f0b73..0e04501 100644 --- a/API/Schema/MangaConnectors/Global.cs +++ b/API/Schema/MangaConnectors/Global.cs @@ -1,4 +1,6 @@ -namespace API.Schema.MangaConnectors; +using API.Schema.Contexts; + +namespace API.Schema.MangaConnectors; public class Global : MangaConnector { diff --git a/API/Tranga.cs b/API/Tranga.cs index 753f26d..1024568 100644 --- a/API/Tranga.cs +++ b/API/Tranga.cs @@ -1,4 +1,5 @@ using API.Schema; +using API.Schema.Contexts; using API.Schema.Jobs; using API.Schema.MangaConnectors; using API.Schema.NotificationConnectors; @@ -30,12 +31,7 @@ public static class Tranga } IServiceProvider serviceProvider = (IServiceProvider)serviceProviderObj!; using IServiceScope scope = serviceProvider.CreateScope(); - PgsqlContext? context = scope.ServiceProvider.GetService(); - if (context is null) - { - Log.Error("PgsqlContext is null"); - return; - } + NotificationsContext context = scope.ServiceProvider.GetRequiredService(); try { @@ -64,12 +60,7 @@ public static class Tranga { Log.Info($"Sending notifications for {urgency}"); using IServiceScope scope = serviceProvider.CreateScope(); - PgsqlContext? context = scope.ServiceProvider.GetService(); - if (context is null) - { - Log.Error("PgsqlContext is null"); - return; - } + NotificationsContext context = scope.ServiceProvider.GetRequiredService(); List notifications = context.Notifications.Where(n => n.Urgency == urgency).ToList(); if (!notifications.Any()) @@ -117,6 +108,8 @@ public static class Tranga } Log.Info(TRANGA); + Log.Info("Loading Jobs"); + context.Jobs.Load(); Log.Info("JobStarter Thread running."); while (true) { @@ -146,7 +139,7 @@ public static class Tranga List dueJobs = waitingJobs.Where(j => j.NextExecution < DateTime.UtcNow).ToList(); List busyConnectors = GetBusyConnectors(runningJobs); - List startJobs = FilterJobPreconditions(dueJobs, busyConnectors); + List startJobs = FilterJobPreconditions(context, dueJobs, busyConnectors); //Start Jobs that are allowed to run (preconditions match) foreach (Job job in startJobs) @@ -194,9 +187,13 @@ public static class Tranga return busyConnectors.ToList(); } - private static List FilterJobPreconditions(List dueJobs, List busyConnectors) => + private static List FilterJobPreconditions(PgsqlContext context, List dueJobs, List busyConnectors) => dueJobs - .Where(j => j.DependenciesFulfilled) + .Where(j => + { + context.Entry(j).Collection(j => j.DependsOnJobs).Load(LoadOptions.ForceIdentityResolution); + return j.DependenciesFulfilled; + }) .Where(j => { //Filter jobs with busy connectors