Skip to content

Add manual progress fallback when progress package unavailable#124

Merged
matt-graham merged 15 commits into
UCL:mainfrom
jennajiali:progress-fallback
Jun 25, 2026
Merged

Add manual progress fallback when progress package unavailable#124
matt-graham merged 15 commits into
UCL:mainfrom
jennajiali:progress-fallback

Conversation

@jennajiali

@jennajiali jennajiali commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

#29

Summary

Fixes the issue where calling sample_chain() with show_progress_bar = TRUE would silently produce no output if the progress package was not installed, making it appear to the user as though the program had halted — particularly problematic for long chains.

When progress is unavailable, the function now emits a one-time informational message and then prints percentage-based progress updates with elapsed time at 10% intervals to the console.

Example output when progress is not installed:

progress package is not installed, so will print progress updates below.
Warm-up: 10% done (1000/10000 iterations) | elapsed: 0.6s
Warm-up: 20% done (2000/10000 iterations) | elapsed: 1.2s
...
Warm-up: 100% done (10000/10000 iterations) | elapsed: 6.1s
Main: 10% done (1000/10000 iterations) | elapsed: 0.6s
...
Main: 100% done (10000/10000 iterations) | elapsed: 6.0s

Changes

R/chains.R

  • Add is_package_available() helper — a thin wrapper around requireNamespace() that lives in the package namespace, making it mockable in tests via with_mocked_bindings()
  • Split use_progress_bar into two booleansprogress_available (is the package installed?) and show_progress_bar (did the user ask for progress?) are now kept separate and passed independently through sample_chain() and chain_loop(), so the fallback path can distinguish between the two cases
  • Upfront warning in sample_chain() — prints a one-time message when show_progress_bar = TRUE but progress is unavailable
  • Updated get_progress_bar() signature — now accepts show_progress_bar and progress_available separately instead of the collapsed use_progress_bar
  • Fallback branch in chain_loop() — added else if branch alongside the existing progress bar tick, printing a formatted stage: X% done (n/total) | elapsed: Xs message at every 10% interval using proc.time() (base R, no dependencies)
  • Post-loop 100% guard — prints a final "100% done" message after the loop when n_iteration is not an exact multiple of tick_amount, ensuring completion is always reported
  • Updated @param show_progress_bar roxygen doc — reflects that the parameter now controls both the progress bar (when progress is installed) and the fallback text output (when it is not)

tests/testthat/test-chains.R

  • Add make_fallback_test_inputs() helper — extracts shared setup (target distribution, adapters, initial position) used by both new tests into a single function to avoid duplication
  • New test: fallback messages are emitted — mocks is_package_available() to return FALSE, captures all messages with capture_messages(), and asserts the correct total count, that the upfront warning is present, and that both 10% and 100% interval messages appear
  • New test: silent when show_progress_bar = FALSE — same mock, asserts expect_no_message() confirming the fallback is correctly gated on the user's flag

Testing

All existing tests continue to pass. The two new tests covering the fallback path and the silent-when-disabled case also pass.

Notes

This PR is a draft / work in progress

When show_progress_bar = TRUE but the progress package is not installed,
rather than silently doing nothing, emit a one-time warning then print
10%-interval progress messages with elapsed time to the console.

Changes in R/chains.R:
- Add is_package_available() wrapper around requireNamespace() to allow
  mocking in tests
- Replace single use_progress_bar boolean with two separate booleans
  (show_progress_bar, progress_available) passed through sample_chain()
  and chain_loop(), keeping the two concerns distinct
- Print upfront message in sample_chain() when progress package is
  missing but progress bar was requested
- Update get_progress_bar() signature to accept the two booleans
- Add start_time tracking in chain_loop() using proc.time()
- Add fallback else-if branch in chain_loop() printing formatted
  percentage/elapsed messages at 10% intervals
- Add post-loop guard to print 100% done when n_iteration is not a
  multiple of tick_amount
- Update @param show_progress_bar roxygen doc to reflect new behaviour

Changes in tests/testthat/test-chains.R:
- Add make_fallback_test_inputs() helper to deduplicate test setup
- Add test verifying fallback messages are emitted (count, 10%, 100%)
- Add test verifying no messages when show_progress_bar = FALSE
@jennajiali jennajiali marked this pull request as draft June 13, 2026 20:10
@jennajiali jennajiali marked this pull request as ready for review June 13, 2026 20:11
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (504f5ea) to head (b6dc6b0).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #124   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           11        11           
  Lines          595       620   +25     
=========================================
+ Hits           595       620   +25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@matt-graham matt-graham left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi @jennajiali. This is looking really good. I have suggested some minor changes to resolve linter warnings and improve code readability and maintainability a bit.

As well as the linter warnings, currently the checks are also failing as your changes to the roxygen comment for sample_chains needs a corresponding change to the man/sample_chain.Rd manual page which is generated from this comment. If you have devtools loaded, running document() in an R session should regenerate this file and then you can commit updated version.

Some of the failing checks are run as part of our pre-commit (https://pre-commit.com/) hooks for the project. If you install pre-commit locally and install the hooks in your local repository by running

pre-commit install

from the root of the repository, this will run the checks each time you try to make a commit and give an error and/or changes to fix when you try to commit.

Comment thread tests/testthat/test-chains.R Outdated
Comment thread tests/testthat/test-chains.R Outdated
Comment thread R/chains.R Outdated
Comment thread R/chains.R Outdated
Comment thread R/chains.R Outdated
Comment thread R/chains.R Outdated
@matt-graham matt-graham linked an issue Jun 17, 2026 that may be closed by this pull request
jennajiali and others added 6 commits June 18, 2026 12:13
The linter warning here is due to indentation. We can avoid need to split line and repetition of chain_iteration %% tick_amount == 0 expression by factoring out in to a variable and reusing. We also don't need to explicitly check !progress_available in second condition as this is implied by the fact first condition didn't evaluate to TRUE.

Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
Reflowing this line should fix linter line length warning.

Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
…resolve linter warning

To reduce line length to avoid linter warning here and make code more readable we can define a variable progress_unfinished which checks whether progress updates are complete and then use this in conditions. We ideally also want to use else if here rather than an independent if clause as we don't need to check the second condition if the first evaluates to TRUE. This also suggests changing progress$finished to use progress_unfinished variable as this should be functionally equivalent and makes it clear we are using the same condition irrespective of whether using the progress package or not.
Comment thread R/chains.R Outdated
Comment thread R/chains.R Outdated
Comment thread tests/testthat/test-chains.R Outdated
jennajiali and others added 6 commits June 18, 2026 21:52
This will cause the linter warning on cyclomatic complexity for this function to be ignored. As per the comment below it's not clear how useful the cyclomatic complexity measure is here so we may want to consider disabling globally, and either way I think it is justified to ignore it for now here and potentially consider possible refactorings to reduce complexity of this function in a separate PR.

Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
…tion %% tick_amount != 0`


Using a number of iterations which is not an exact multiple of 10 here will ensure the final conditions which ensure progress updates are completed when n_iteration %% tick_amount != 0 are entered as part of the tests and so avoid the warning about that line of code not being covered by tests from codecov check.

Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
@matt-graham

Copy link
Copy Markdown
Collaborator

Hi @jennajiali - apologies for all the back and forth. Some of my suggested changes introduced a new styler error causing the pre-commit check to fail and also didn't fix the missing lines in coverage as I'd expected. I've opened a PR off the top of your PR in jennajiali#1 which should resolve the remaining failing checks 🤞 (or at least I get no styler warnings and 100% coverage locally with those changes).

Minor fixes to progress fallback PR
Comment thread R/chains.R Outdated
🤞 this will resolve both the styler warning (which wants this comment to be on a separate line) and the linter warning (which requires the nolint directive to be on the line used to open the function) by disabling styler for this specific line. Running both styler and lintr checks locally with this change doesn't raise any warnings.

Co-authored-by: Matt Graham <matthew.m.graham@gmail.com>
@matt-graham matt-graham merged commit 2930938 into UCL:main Jun 25, 2026
11 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.

Show basic progress updates when progress package not installed

2 participants