Skip to content

Conversation

evan314159
Copy link
Contributor

Changes
On filesystems like ZFS with higher modification time accuracy than the database, the comparison itemLastModifiedFileSystem != modificationDate fails. Allow a tolerance of 1 second.

Issues
No issue raised. On ZFS causes every file to be rescanned on every scan run.

On filesystems like ZFS with higher modification time accuracy than the database, the comparison itemLastModifiedFileSystem != modificationDate fails.  Allow a tolerance of 1 second.
@evan314159 evan314159 changed the title MetadataService: fix file modification date comparison fix file modification date comparisons Jul 21, 2025
@Shadowghost
Copy link
Contributor

I wouldn't mind merging this but I use ZFS too and never had any issue with this while testing before and after we released the RCs.

@evan314159
Copy link
Contributor Author

I never noticed this until I put 40k music tracks into Jellyfin and found scans took all day and reprocessed all media. With debugging enabled I recorded logs like:

[08:42:41] [DBG] [31] MediaBrowser.Providers.TV.EpisodeMetadataService: File modification time changed from 03/12/2025 13:14:21 to 03/12/2025 13:14:21:

With the changes a library scan takes a few minutes.

@Shadowghost
Copy link
Contributor

But EpisodeMetadataService should not trigger on music library?

@evan314159
Copy link
Contributor Author

The problem was on all my media and that episode happened to be the one I chose to reference in the jellyfin developer chat, so I had a record of it in the chat to give here.

@Shadowghost Shadowghost requested a review from a team July 21, 2025 14:32
Copy link
Member

@JPVenson JPVenson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to find a better way in the long term to do those comparisions like truncating the timestamps to ms accuracy in the DirectoryService and FileService but for now that will do it

@@ -49,7 +49,7 @@ public bool HasChanged(BaseItem item, IDirectoryService directoryService)
if (item.IsFileProtocol)
{
var file = directoryService.GetFile(item.Path);
return file is not null && file.LastWriteTimeUtc != item.DateModified;
return file is not null && item.DateModified.Subtract(file.LastWriteTimeUtc).Duration().TotalSeconds > 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is copied in so many places now that I think it warrants an extension/utility method.

@evan314159
Copy link
Contributor Author

We have to find a better way in the long term to do those comparisions like truncating the timestamps to ms accuracy in the DirectoryService and FileService but for now that will do it

FileService will return whatever with whatever accuracy on a given platform, the database will return with whatever accuracy on a given platform, and Jelly should not care as long as the file modification date is sufficiently different for its purposes.

For this change "sufficiently different" was chosen to be 1 second, but there is existing code in Jelly that works the same way for "sufficiently different" being 1 day instead (for once per day updates). It just can't directly compare fileModified == databaseModified, just like floating point values can't be directly compared with == because floating point accuracy can vary.

The code is simple and robust; if we are worried about it being ugly, it could easily be done as a helper function (e.g. if fileChanged(databaseModified, fileModified, accuracySeconds = 1) { } and then is also usable in those cases using a 1 day resolution.

@crobibero crobibero merged commit 6f49782 into jellyfin:master Jul 28, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants