Skip to content

Conversation

@mjc
Copy link
Owner

@mjc mjc commented Jan 20, 2026

Summary

This PR fixes a long-standing bug where file renames weren't being detected by Sonarr/Radarr after re-encoding. The root cause was using fixed Process.sleep(5000) calls instead of actually waiting for async commands to complete.

Key changes:

  • Replace hard-coded delays with proper command status polling
  • Add wait_for_command/3 and refresh_*_and_wait/2 functions to wait for Sonarr/Radarr commands to complete
  • Run refresh_and_rename in background task to avoid blocking encoding pipeline
  • Improve error handling for invalid video dimensions
  • Add integration test scripts for debugging

Why This Matters

Previously, the flow was:

  1. Trigger refresh command (returns immediately with command ID)
  2. Sleep 5 seconds (fixed, unreliable)
  3. Check for renameable files (might not be ready yet)
  4. Send rename command

Now it's:

  1. Trigger refresh command
  2. Poll until refresh completes (10-15+ seconds, variable)
  3. Check for renameable files (definitely ready)
  4. Send rename command
  5. Poll until rename completes (1-2 seconds)

The entire operation runs in a background task, so it doesn't block the encoding pipeline.

Testing

Added three standalone test scripts:

  • scripts/test_sonarr_rename.exs - Tests Sonarr rename flow with file manipulation
  • scripts/test_radarr_rename.exs - Tests Radarr rename flow with file manipulation
  • scripts/test_app_rename.exs - Tests actual application code using Sync.refresh_and_rename_from_video

All tests pass with both services. The fix has been verified to reliably rename files regardless of server response time.

Files Changed

  • lib/reencodarr/services/sonarr.ex - Add command polling, update rename to wait
  • lib/reencodarr/services/radarr.ex - Add command polling, update rename to wait
  • lib/reencodarr/sync.ex - Use refresh_*_and_wait functions instead of fixed sleep
  • lib/reencodarr/post_processor.ex - Run refresh_and_rename async in background task
  • Various: Improve error handling and validation

🤖 Generated with Claude Code

mjc and others added 5 commits December 11, 2025 11:30
The bug was that after mark_as_reencoded returned the updated video,
we were still passing the old video struct to finalize_and_sync,
which meant the refresh_and_rename call was using stale video data.
- Add retry logic with exponential backoff for getting renameable files
- Validate video dimensions in MediaInfoExtractor before extraction
- Improve error handling throughout the pipeline
- Simplify rename flow by always renaming all renameable files
- Extract rename logic into separate, testable functions
- Update dependencies to latest versions

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The rename flow was unreliable because it used fixed Process.sleep(5000)
calls instead of waiting for commands to actually complete. Refresh
commands can take 10-15+ seconds depending on server load.

Changes:
- Add command polling functions to sonarr.ex and radarr.ex:
  - get_command_status/1 - checks command status by ID
  - wait_for_command/3 - polls until command completes
  - refresh_series_and_wait/2 and refresh_movie_and_wait/2
- Update Sync.refresh_operations to use refresh_*_and_wait
- Update rename execution to wait for rename command to complete
- Fix refresh_and_rename_all_series to wait for refresh completion
- Add integration test scripts for debugging rename issues

The flow now properly waits for each async command to complete before
proceeding, making it reliable regardless of server response times.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The post-processor now spawns the refresh_and_rename in a background
task via TaskSupervisor instead of blocking. This prevents the encoding
pipeline from waiting 10-20+ seconds for Sonarr/Radarr commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings January 20, 2026 19:16
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug in the Sonarr/Radarr rename flow by replacing unreliable fixed-delay sleeps with proper command status polling. The changes ensure that refresh operations complete before attempting to rename files, preventing race conditions that caused the rename flow to fail.

Changes:

  • Replaced Process.sleep(5000) with actual command completion polling via new wait_for_command and refresh_*_and_wait functions
  • Moved refresh-and-rename operations to background tasks to avoid blocking the encoding pipeline
  • Added validation for video dimensions (width/height) during MediaInfo extraction to handle corrupted data gracefully
  • Added three integration test scripts for debugging Sonarr/Radarr rename flows

Reviewed changes

Copilot reviewed 12 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scripts/test_sonarr_rename.exs New standalone integration test for Sonarr rename functionality
scripts/test_radarr_rename.exs New standalone integration test for Radarr rename functionality
scripts/test_app_rename.exs New test script for application-level rename flow
lib/reencodarr/services/sonarr.ex Added command polling functions, removed fixed delays, simplified rename logic
lib/reencodarr/services/radarr.ex Added command polling functions, removed fixed delays, simplified rename logic
lib/reencodarr/sync.ex Updated to use new wait functions, added error handling for invalid dimensions
lib/reencodarr/post_processor.ex Changed to spawn refresh-and-rename as async background task
lib/reencodarr/media/video.ex Added error handling for MediaInfo extraction failures
lib/reencodarr/media/media_info_utils.ex Added dimension validation returning error tuples for invalid data
lib/reencodarr/media/media_info_extractor.ex Added dimension validation with warning logs
lib/reencodarr/analyzer/processing/pipeline.ex Updated to handle error tuples from extraction, improved logging
lib/reencodarr/ab_av1/progress_parser.ex Fixed regex to support GiB/MiB file size formats
mix.lock Routine dependency updates
flake.lock Routine nixpkgs update

mjc and others added 2 commits January 20, 2026 14:23
- Use function clauses with guards instead of cond for rename_files validation
- Simplify parse_renameable_files by extracting collect_results helper
- Remove trivial determine_files_to_rename function
- Simplify refresh_operations by removing unnecessary else blocks
- Consolidate refresh_and_rename_from_video with service type dispatch
- Extract coerce_to_integer helper to reduce duplication
- Fix default parameter placement in rename_movie_files

These changes improve readability and follow Elixir conventions more closely.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes in response to Copilot PR review:

1. **Task error handling** - Handle Task.Supervisor.start_child results
   properly to detect and log task startup failures instead of ignoring them.
   Extracted to spawn_refresh_and_rename_task helper to reduce nesting.

2. **Exponential backoff** - Implement actual exponential backoff (1s, 2s, 4s)
   for retry_get_renameable_files instead of fixed 3s delay. This reduces
   unnecessary waiting when files are ready quickly.

3. **Test coverage** - Add test files documenting the integration tests:
   - test/reencodarr/services/sonarr_test.exs
   - test/reencodarr/services/radarr_test.exs
   These reference scripts/test_app_rename.exs which provides comprehensive
   integration test coverage for wait_for_command, refresh_*_and_wait, and
   exponential backoff logic with live API responses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 16 changed files in this pull request and generated 10 comments.

…ocumentation

Fixes addressing 10 new Copilot review threads:

1. Width/height validation: Check for negative values (w <= 0 or h <= 0) instead of just zero
   - Updated both media_info_utils.ex and media_info_extractor.ex
   - Defensive programming to catch corrupted MediaInfo data

2. Remove unused file_ids parameter from public API
   - sonarr.ex: Removed from rename_files/1 (was ignored with underscore)
   - radarr.ex: Removed from rename_movie_files/1 (was ignored with underscore)
   - Updated all call sites to use parameter-less versions
   - Clarifies that function always renames all renameable files

3. Add comprehensive exponential backoff documentation
   - sonarr.ex: Added comments explaining 1s, 2s, 4s, 8s delay pattern
   - radarr.ex: Same documentation for consistency
   - Comments explain the mathematical formula: base_delay * 2^(attempt-1)

4. Simplified sync.ex refresh_operations
   - Removed empty list parameters from Sonarr/Radarr calls
   - Code now matches the simplified function signatures

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@mjc mjc merged commit 35990b7 into main Jan 21, 2026
1 check passed
@mjc mjc deleted the fix/sonarr-rename branch January 21, 2026 02:35
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.

2 participants