Files
pgsql-jellyfin/docs/LIBRARYMONITOR_DISPOSAL_FIX_SUMMARY.md
wjones 7eb2b445cb Postgres perf, path migration, and shutdown race fixes
- Major query performance boost: replaced correlated subqueries with DistinctBy() in BaseItemRepository, added episode deduplication index, and increased default command timeout to 120s.
- Fixed LibraryMonitor shutdown race: added disposal checks and exception handling in FileRefresher to prevent ObjectDisposedException.
- Added PowerShell and SQL utilities for fixing Linux paths in config files and database; new scripts for WebDir and path migration.
- Auto-fix for WebDir in startup.json on load; new helper scripts and docs.
- Added automated weekly DB performance monitoring scripts and reporting.
- Expanded documentation and README for all fixes, scripts, and migration steps.
- Updated SQL scripts for index creation and diagnostics; improved output handling.
- Updated db-config defaults and added new diagnostic/report files.
2026-03-05 08:56:42 -05:00

95 lines
2.3 KiB
Markdown

# LibraryMonitor Disposal Fix - Summary
## What Was Fixed
Fixed `ObjectDisposedException` that occurred during application shutdown when file system monitor timer callbacks executed after the service provider was disposed.
## Error Message
```
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
at Emby.Server.Implementations.IO.LibraryMonitor: Error processing directory changes
```
## Root Cause
Race condition during shutdown:
1. Application begins shutdown and disposes `IServiceProvider`
2. `LibraryMonitor` disposal starts
3. `FileRefresher` timer callback fires **before** timer is fully disposed
4. Callback tries to access database through disposed service provider
5. Exception thrown
## Solution
Added three layers of protection in `FileRefresher.cs`:
### 1. Early Exit Check
```csharp
private void OnTimerCallback(object? state)
{
if (_disposed) return; // ← Added
// ...
}
```
### 2. Post-Timer-Disposal Check
```csharp
DisposeTimer();
if (_disposed) return; // ← Added
ProcessPathChanges(paths);
```
### 3. Exception Handling
```csharp
try
{
itemsToRefresh = paths.Select(GetAffectedBaseItem)...;
}
catch (ObjectDisposedException) // ← Added
{
_logger.LogDebug("Service provider disposed during shutdown");
return;
}
```
## Impact
- ✅ Clean application shutdowns
- ✅ No more `ObjectDisposedException` errors in logs
- ✅ No impact on normal operation
- ✅ Graceful handling of shutdown race conditions
## Files Modified
- **Emby.Server.Implementations\IO\FileRefresher.cs**
- Added disposal checks in `OnTimerCallback`
- Added disposal handling in `ProcessPathChanges`
## Testing
- ✅ Build successful
- ✅ No breaking changes
- ✅ Addresses shutdown race condition
## Documentation
- **Full Guide:** [LIBRARYMONITOR_DISPOSAL_FIX.md](./LIBRARYMONITOR_DISPOSAL_FIX.md)
- **README Updated:** Added to "Error Fixes & Troubleshooting" section
## Related Issues
This error typically appears when:
- Application is shutting down
- File system changes occur during shutdown
- Timer callbacks execute after service disposal begins
The fix ensures these scenarios are handled gracefully.
---
**Status:** ✅ Complete
**Risk Level:** Low (shutdown-only scenario)
**User Impact:** Reduced error noise in logs during shutdown