The dashboard lists 2 of the 15 jobs upstream runs #97
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Upstream registers 20
IScheduledTaskimplementations at the pinned ref. Setting aside the three that are not ours —PluginUpdates, and the Live TV pairRefreshInternetChannelsandRefreshGuide, both of which hide themselves when nothing is configured — that leaves 17, of which we declare 2 (crates/jellyfin-app/src/admin/tasks.rs).RefreshLibraryRefreshPeopleRefreshChapterImagesRefreshTrickplayImagesMoveTrickplayImagesKeyframeExtractionKeyframeDataTaskExtractMediaSegmentsAudioNormalizationOptimizeDatabaseTaskVACUUM/ANALYZEDeleteTranscodeFilesDeleteCacheFilesCleanLogFilesCleanActivityLogCleanupUserDataTaskTmdbRefreshUpcomingEpisodesDownloadSubtitlesDownloadLyricsThe last two need a remote provider that upstream itself only gets from a plugin, so in a stock install they are registered and do nothing — they are on the list because the dashboard shows them and an operator counts them.
The module doc in
tasks.rsgives the rule this was written under, and it is a good rule: one named here that did nothing would be a button an operator presses and watches succeed. So this issue is not "declare fifteen tasks" — it is the umbrella for the ones filed separately, and it closes when they do.Upstream's list is
Emby.Server.Implementations/ScheduledTasks/Tasks/, plusMediaBrowser.Providers/{Trickplay,MediaInfo,Lyric}/, plussrc/Jellyfin.MediaEncoding.Hls/ScheduledTasks/.Where to start
This is an umbrella. The work is in the issues it points at: chapter images #98, trickplay #99,
keyframes #100, media segments #101, audio normalization #102, the six
maintenance sweeps #103, the activity log #104, and TMDb's upcoming-episodes
task (with #106) — plus the scheduler itself, #95, without which any of them
would be a button rather than a job.
The rule to keep while closing it is the one already written at the top of
crates/jellyfin-app/src/admin/tasks.rs: one named here that did nothing would be abutton an operator presses and watches succeed. So a task is declared when it
does something, not when the route can list it.
Upstream's list is
Emby.Server.Implementations/ScheduledTasks/Tasks/, plusMediaBrowser.Providers/{Trickplay,MediaInfo,Lyric}/, plussrc/Jellyfin.MediaEncoding.Hls/ScheduledTasks/. The keys in the table aboveare upstream's own and are what a client matches a task by — take them from the
source rather than retyping them.
How to know it is done
Every row in the table is either implemented or has an argued reason to be
absent, and
/ScheduledTasksdiffs clean against the reference for the tasksboth servers have.
House rules
CLAUDE.mdis the short version and these are the parts that bite: tests rununder
cargo nextest; upstream's source is the checkout inupstream/at thepin (
v12.0-rc5,6d501ba4) and not the clone beside the repository;generated files are regenerated rather than edited; a comment says what the code
does, not how it got there; and
Dnreferences stay out of code and comments.ARCHITECTURE.mddecides which crate a thing goes in and which dependency edgesare illegal,
DECISIONS.mdsays why a rule exists.The reference pair is
cargo xtask reference up(andreference provision,which is idempotent); a run is
cargo run -p jellyfin-harness -- replay --upstream URL --ours URL --scenario FILE --out DIR,with
diff-dbfor the two databases.crates/jellyfin-harness/README.mdsayswhat a diff means and what an ignore entry has to carry — every entry needs a
reason and an expiry milestone, and an adds-only history is the smell the risk
table names.
Checked the table against the reference rather than against the C#, with the pair up.
/ScheduledTaskson the pinned image lists 20; setting asidePluginUpdatesand the two Live TV rows it hides when nothing is configured leaves 17, of which this server now declares 11 — up from 2 when this was filed.Batch C landed the six maintenance sweeps (#103). Each was measured against the reference by id:
/ScheduledTasks/{id}for all six diffs clean — the key, the name, the category, the description and the triggers agree byte for byte, and the six ids are intasks.jsonso they go on being diffed.RefreshLibraryRefreshPeopleRefreshChapterImagesKeyframeExtractionAudioNormalizationOptimizeDatabaseTaskDeleteTranscodeFilesDeleteCacheFilesCleanLogFilesCleanActivityLogCleanupUserDataTaskRefreshTrickplayImagesMoveTrickplayImagesTaskExtractMediaSegmentsTmdbRefreshUpcomingEpisodesDownloadSubtitlesDownloadLyricsThe four still absent, and why
RefreshTrickplayImagesandMoveTrickplayImagesare #99's, in batch D. They are the two rows this issue cannot close without.TaskExtractMediaSegmentsis settled and stays absent. #101 measured it: with no provider registered upstream's own task completes, writes no row and marks no item, and there is no per-item analysed state in the schema at all. Declaring it would be the buttonadmin/tasks.rsrefuses in its module doc. Recorded inMILESTONES.md.DownloadSubtitlesandDownloadLyricsare the same argument and it holds: both need a remote provider upstream itself only gets from a plugin, so in a stock install they are registered and do nothing. The original text called them "on the list because the dashboard shows them and an operator counts them" — that is not enough under the module's own rule, and the honest position is that declaring either would be a name with no work behind it. Filing them as argued absent rather than to do, on the same evidence #101 was closed on.TmdbRefreshUpcomingEpisodesis the one row with no argument yet. Unlike the three above it has a provider this server could drive: #106 landed the TMDb TV side, and the closing note there does not say what happened toTmdbMissingEpisodeProvideror the task that runs it./Shows/Upcomingis still answered from whatever premiere dates the fixture happens to carry. Someone should either port it or write down why not — it does not belong on the argued-absent list until somebody has looked.What this closes on
Twelve of seventeen rows are now either implemented or argued. Left: the two trickplay rows (#99, batch D) and the upcoming-episodes task above. This issue closes when #99 lands and the last row has an answer either way.
Closing. The count in the title was stale twice over, and the corrected accounting is measured off the reference rather than read out of the C#.
GET /ScheduledTaskson the pinned reference returns 20, of which two carryIsHidden: true—RefreshGuideandRefreshInternetChannels, the Live TV pair. So a dashboard upstream shows 18, not the 17 this issue set asidePluginUpdatesto reach: upstream does show it, under anApplicationcategory. This server declares 12.The six
Each is absent because it would find nothing to do, which is this file's own rule rather than a new one:
PluginUpdatesDownloadSubtitlesISubtitleProviderof its own — only the interface, the manager and the DI hook; every fetcher is a plugin'sDownloadLyricsILyricProvider.CoreAppHost.cs:101populates it fromGetExportTypesaloneTaskExtractMediaSegmentsRunSegmentPluginProviders, and there is no in-boxIMediaSegmentProviderTmdbRefreshUpcomingEpisodesIsVirtualItemsetMoveTrickplayImageslibraryOptions.SaveTrickplayWithMedia, which this server does not read — every sheet it writes is in the data directoryThe last two are gaps rather than permanent decisions.
MoveTrickplayImagesbecomes a task the moment the library option it services is honoured, which is #147. Nothing files the virtual-item one; it is noted inDECISIONS.mdrather than left implicit.The twelve, and what was actually unmeasured
All twelve match the reference exactly on key, name, description, category and triggers — checked field by field against
/ScheduledTaskson the running instance, and against each task's source at the pin.The gap this issue's second criterion was pointing at was not the count.
scenarios/tasks.jsondiffed eight of the twelve by id and never fetched the listing, so four tasks both servers have —KeyframeExtraction,AudioNormalization,RefreshChapterImages,RefreshTrickplayImages— were diffed against nothing at all. They are in the scenario now. Replayed against the pair: 22 responses, 0 differences, and the four new ids resolve on both sides, which incidentally proves the id derivation for all four.What is recorded
jellyfin_app::admin::tasks::ABSENT— the six and the reason for each.DECISIONS.mdD34 — the rule, the two rejected alternatives, and why the listing carries no ignore entry: hiding@bodyonGET /ScheduledTaskswould hide the whole route, and the difference is six array members rather than a field. This also settles the position #127 left open when it sorted the listing by name — the per-task reads were meant to stand until the count caught up, and for four of the six it never will.crates/jellyfin-harness/README.md— why the listing is not asked for.Landed in
05901d7.