with_progress() warns about receiving progress
updates after the progressor has finished. Previously, only the global
‘progression’ handler would do this.Using with_progress() together with
handlers(global = TRUE) would produce a warning on
“Received a progression ‘update’ request (…) but is not listening to
this progressor”.
Shiny apps running as background jobs in RStudio could fail with an error “object ‘RStudio.Version’ of mode ‘function’ was not found”. This error occurred sporadically.
handler_slowdown() for slowing down a full progress
run a certain amount of time (in seconds).Package failed to load in the Positron environment due to an “object ‘RStudio.Version’ of mode ‘function’ was not found” error.
In Positron, messages produced while progress is reported were prepended by a newline to standard output, even when there is no stdout buffered. This is due to a bug in Positron, which this version of the package works around.
Renamed handler_rpushbullet() argument
device to devices.
Fixed thinko bug in
example("handler_ntfy").
handler_ntfy() for reporting on progress via the
Ntfy.sh Messaging Service using the ntfy package.withProgressShiny() could produce an `if
(config$max_steps ==
handlers(new_handlers) would return
NULL, instead of list(), if there were no
prior handlers set.
handler_cli(..., format_done = "...", clear = TRUE)
would not render the format_done message, if set.
progressr.options help page is now listed in the
help index.Now the ‘shiny’ and ‘filesize’ handlers are enabled by default.
Previously, they were only enabled in interactive mode, but as these are
frequently used also in non-interactive mode, it’s less confusing if
they’re always enabled, e.g. Shiny applications are often run via a
Shiny servers. These handlers can be disabled by setting R option
progressr.enable to FALSE.
Option progressr.intrusiveness.auditory has been
renamed to progressr.intrusiveness.audio.
Add handler_rpushbullet() for reporting on progress
via the Pushbullet Messaging Service using the
RPushbullet package.
Now also ‘beepr’, ‘debug’, ‘filesize’, ‘notifier’, ‘rpushbullet’, ‘shiny’, ‘tkprogressbar’, and ‘winprogressbar’ handlers report on interrupts.
Now progress updates of type “finish” supports also updating the
progress state, e.g. you can do
p(amount = 1.0, type = "finish") whereas previously you had
to do p(amount = 1.0) and then
p(type = "finish") resulting in two progress conditions
being signaled.
When using multiple progression handlers, it would only be first one that was updated as the progressor completed, whereas any following ones would not receive that last update.
The ‘cli’ handler would output a newline when completed.
The ‘cli’ handler did not handle zero-length progressors
resulting in
Error in rep(chr_complete, complete_len) : invalid 'times' argument
when the progressor completed.
The ‘cli’ handler did not work when the cli
package was configured to report on progress via
progressr, i.e. when setting
options(cli.progress_handlers = "progressr").
with_progress() and without_progress()
disables the global progress handler temporarily while running to avoid
progress updates being handled twice. Previously, it was, technically,
possible to have two different progress handlers intertwined.Add handler_cli() for rendering progress updates via
the cli package and its
cli::cli_progress_bar().
Now handler_progress() creates a
progress progress bar that is always rendered by
forcing
progress::progress_bar$new(..., force = TRUE).
handler_txtprogressbar() gained support for
ANSI-colored char ASCII and Unicode symbols.
Now with_progress() asserts that the number of
active “output” sinks is the same on exit as on enter, and that the last
one closed is the one that was created. If not, an informative error
message is produced.
Now all progress handlers assert that the number of active “output” sinks is the same on exit as on enter.
Code that relied on the superseded crayon package has now been updated to use the cli package.
Using with_progress() while the global progress
handler was enabled could result in errors for the cli
handler, and possibly for other progression handlers developed in the
future. Because of this, with_progress() and
without_progress() now disables the global progress handler
temporarily while running.
The pbmclapply() handler went from 0 to 100% in one
step, because we forgot to set the max:imum value.
When the using a ‘winprogressbar’ or a ‘tkprogressbar’ handler,
progression messages updates the label component of the
progress panel. Now, it is also possible to update the
title component based on progression messages. How the
title and label components are updated and
from what type of progression message is configured via the new
inputs argument. For example,
inputs = list(title = "sticky_message", label = "message")
causes progression messages to update the label component
and sticky ones to update both. For backward compatible reasons, the
default is
inputs = list(title = NULL, label = "message").
Now the demo function slow_sum() outputs also
“sticky” messages.
<em> tags in HTML-generated help
pages.y <- plyr::llply(X, slow_sum, .parallel = TRUE, .progress = "progressr").The ‘plyr’ progress plugin stopped working with progressr 0.8.0.
Warnings on stray progression conditions could
appear with an empty message.
A progressor that signaled progress beyond 100% prevented any further progressors in the same environment to report on progress.
It was not possible to reuse handlers of type ‘progress’ more than once, because they did not fully reset themselves when finished.
The ‘pbcol’ progression handler did not respect
clean = FALSE.
progress() is defunct in order to re-use it
for other purpose. It is unlikely that anyone really used this function,
but if you did, then use cond <- progression() to create
a progression condition and then use
withRestart(signalCondition(cond), muffleProgression = function(p) NULL)
to signal it.The progressor function created by progressor() no
longer “inherit” objects from the calling environment, which would, for
instance, result in those objects to be exported to parallel workers
together with the progressor function, which in turn would come with
large time and memory costs.
progressor() no longer records the call stack for
progressions by default, because that significantly increases the size
of these condition objects, e.g. instead of being 5 kB it may be 500 kB.
If a large number of progress updates are signaled and collected, as
done, for instance, by futures, then the memory consumption on the
collecting end could become very large. The large sizes would also have
a negative impact on the performance in parallelization with futures
because of the extra overhead of transferring these extra large
conditions from the parallel workers back to the main R session. These
issues has been there since progressr 0.7.0 (December
2020). To revert to the previous behavior, use
progressor(..., trace = TRUE).
progressor() gained argument trace to
control whether or not the call stack should be recorded in each
progression condition.
Now print() for progressor functions
and progression conditions report also on the size of the
object, i.e. the number of bytes it requires when serialized, for
instance, to and from a parallel worker.
parallel::mclapply(). This would give a false impression
that progressr updates would work when using
parallel::mclapply(), which is not true. Note however, that
it does indeed work when using the future ‘multicore’ backend, which
uses forks.Creating a new progressor() will now automatically
finish an existing progressor, if one was previously created in the same
environment. The previous behavior was to give an error (see below bug
fix).
R_PROGRESSR_* environment variables are now only
read when the progressr package is loaded, where they
set the corresponding progressr.* option. Previously, some
of these environment variables were queried by different functions as a
fallback to when an option was not set. By only parsing them when the
package is loaded, it decrease the overhead in functions, and it
clarifies that options can be changed at runtime whereas environment
variables should only be set at startup.
When using withProgressShiny(), progression messages
now updates the detail component of the Shiny progress
panel. Previously, it updated the message component. This
can be configured via new inputs argument.
withProgressShiny() gained argument
inputs, which can be used to control whether or not Shiny
progress components message and detail should
be updated based on the progression message, e.g.
inputs = list(message = "sticky_message", detail = "message")
will cause progression messages to update the detail
component and sticky ones to update both.
Now supporting zero-length progressors,
e.g. p <- progressor(along = x) where
length(x) == 0.
Add handlers("rstudio") to report on progress in the
RStudio Console via the RStudio Job interface.
p(amount = 2), it is now possible to also specify the
absolute amount of progress made this far,
e.g. p(step = 42). Argument amount has not
effect when argument step is specified. WARNING: Argument
step should only be used when in full control of the order
when this progression condition is signaled. For example,
it must not be signaled as one of many parallel progress updates
signaled concurrently, because we cannot guarantee the order these
progressions arrive.local() call would
result in: “Error in assign(”…progressor”, value = fcn, envir = envir) :
cannot change value of locked binding for …progressor.”progress() is deprecated in order to re-use it
for other purpose. It is unlikely that anyone really used this function,
but if you did, then use cond <- progression() to create
a progression condition and then use
withRestart(signalCondition(cond), muffleProgression = function(p) NULL)
to signal it.The user can now use handlers(global = TRUE) to
enable progress reports everywhere without having to use
with_progress(). This only works in R (>= 4.0.0) because
it requires global calling handlers.
with_progress() now reports on progress from
multiple consecutive progressors,
e.g. with_progress({ a <- slow_sum(1:3); b <- slow_sum(1:3) }).
A progressor must not be created in the global environment unless
wrapped in with_progress() or
without_progress() call. Ideally, a progressor is created
within a function or a local() environment.
Package now requires R (>= 3.5.0) in order to protect against interrupts.
progressor() gained argument enable to
control whether or not the progressor signals progression
conditions. It defaults to option progressr.enable so that
progress updates can be disabled globally. The enable
argument makes it easy for package developers who already provide a
progress = TRUE/FALSE argument in their functions to
migrate to the progressr package without having to
change their existing API, e.g. the setup becomes
p <- progressor(along = x, enabled = progress). The
p() function created by
p <- progressor(..., enable = FALSE) is an empty
function with near-zero overhead.
Now with_progress() and
without_progress() returns the value of the evaluated
expression.
The progression message can now be created dynamically based on
the information in the progression condition. Specifically,
if message is a function, then that function will called
with the progression condition as the first argument. This
function should return a character string. Importantly, it is only when
the progression handler receives the progression update and calls
conditionMessage(p) on it that this function is
called.
progressor() gained argument message to
set the default message of all progression updates, unless otherwise
specified.
progressor() gained argument
on_exit = TRUE.
Now the progress handler shows also a spinner by
default.
Add the ‘pbcol’ handler, which renders the progress as a colored progress bar in the terminal with any messages written in the front.
Progression handlers now return invisibly whether or not they are finished.
Zero-amount progress updates never reached the progress handlers.
Argument enable for with_progress() had
no effect.
with_progress() makes sure that any output produced
while reporting on progress will not interfere with the progress output
and vice versa, which otherwise is a common problem with progress
frameworks that output to the terminal, e.g. progress-bar output is
interweaved with printed objects. In contrast, when using
progressr we can use message() and
print() as usual regardless of progress being reported or
not.Signaling progress(msg, class = "sticky") will cause
the message to be sticky, e.g. for progress bars outputting to the
terminal, the message will be “pushed” above the progress bar.
with_progress() gained argument
delay_terminal whose default will be automatically inferred
from inspecting the currently set handlers and whether they output to
the terminal or not.
Arguments delay_stdout and
delay_conditions for with_progress() is now
agile to the effective value of the delay_terminal
argument.
Now handler_nnn() functions pass additional arguments in
... to the underlying progress-handler backend,
e.g. handler_progress(width = 40L) will set up
progress::progress_bar$new(width = 40L).
Add environment variables R_PROGRESSR_CLEAR,
R_PROGRESSR_ENABLE, R_PROGRESSR_ENABLE_AFTER,
R_PROGRESSR_TIMES, and R_PROGRESSR_INTERVAL
for controlling the default value of the corresponding
progressr.* options.
Limiting the frequency of progress reporting via handler
arguments times, interval or
intrusiveness did not work and was effectively
ignored.
The progress handler, which uses
progress::progress_bar(), did not support colorization of
the format string when done by the crayon
package.
handlers() did not return invisible (as
documented).
Argument target was ignored for all handler
functions.
Argument interval was ignored for
handler_debug().
The class of handler_<nnn>() functions where
all reset_progression_handler rather than
<nnn>_progression_handler. The same bug caused the
reported name field to be "reset" rather than
"<nnn>".
<name>_handler() to
handler_<name>() to make it easier to use
autocompletion on them.progressor() gained arguments offset
and scale, and transform.
handlers() gained argument append to
make it easier to append handlers.
progression condition with amount = 0
would not update the message.winprogressbar_handler() would produce error
“invalid ‘Label’ argument”.
handlers() did not return a list if the ‘default’
handler was returned.
withProgress2() to
withProgressShiny().handlers() gained argument default
specifying a progression handler to be returned if none is set.Add withProgress2(), which is a plug-in backward
compatibility replacement for shiny::withProgress() wrapped
in progressr::with_progress() where the the “shiny”
progression handler is by default added to the list of progression
handlers used.
Add
demo("mandelbrot", package = "progressr").
.Random.seed to NULL, instead of
removing it, which in turn would produce a warning on “‘.Random.seed’ is
not an integer vector but of type ‘NULL’, so ignored” when the next
random number generated.progressor(along = ...).Now it is possible to send “I’m still here” progression updates
by setting the progress step to zero,
e.g. progress(amount = 0). This type of information can for
instance be used to updated a progress bar spinner.
Add utility function handlers() for controlling
option progressr.handlers.
Progression handlers’ internal state now has a sticky
message field, which hold the most recent, non-empty
progression message received.
with_progress() gained arguments enable
and interval as an alternative to setting corresponding
options progressr.*.
Now option progressr.interval defaults to 0.0 (was
0.5 seconds).
Added print() for progression_handler
objects.
with_progress(..., delay_conditions = "condition"),
introduced in progressr 0.1.0, would also capture
conditions produced by progression handlers,
e.g. progress::progress_bar() output would not be displayed
until the very end.with_progress() now captures standard output and
conditions and relay them at then end. This is done in order to avoid
interweaving such output with the output produced by the progression
handlers. This behavior can be controlled by arguments
delay_stdout and delay_condition.progression condition is identified from the R
session UUID, the progressor UUID, the incremental progression index,
and the progression timestamp.progression conditions that
was non-distinguishable from those previously exported. Adding a
timestamp to the progression condition makes them
distinguishable.Add print() for progression conditions
and progressor functions.
Now the progressors record more details on the session
information. This information is passed along with all
progression conditions as part of the internal owner
information.
Add filesize_handler progression handler.
Add support for times = 1L for progression handlers
which when used will cause the progression to only be presented upon
completion (= last step).
The shutdown control_progression signaled by
with_progress() on exit now contains the
status of the evaluation. If the evaluation was successful,
then status = "ok", otherwise "incomplete".
Examples of incomplete evaluations are errors and interrupts.
Add utils::winProgressBar() progression handler for
MS Windows.
Add support for silent sounds for
beepr::beep().
Add option progressr.enable, which defaults to
interactive().
Precreated progression handlers could only be used once.
with_progress(..., cleanup = TRUE) requires a
withRestart() such that also “shutdown” progressions can be
muffled.
Add argument enable_after for progression
handlers.
Now with_progress(..., cleanup = TRUE) will signal a
generic “shutdown” progression at the end that will trigger all
progression handlers to finish up regardless of all steps have been take
or not.
Now progressions originating from an unknown source are ignored.
The default output format of the
progress::progress_bar() progression handler is now
":percent :bar :message".
The tcltk::tkProgressBar() progression handler now
displays the progression message.
Now the progression condition itself is passed to
the progression reporter functions.
Add ‘debug_handler’ for prototyping and debugging purposes.
Add ‘newline_handler’ to add newlines between output of multiple handlers.
Argument intrusiveness may now be zero. Previously
it had to be a strictly positive value.
Add without_progress() - which causes all
progression conditions to be muffled and ignored.
Progressor functions could produce progression
conditions that had the same identifiers and therefore would be
considered duplicates such that progression handlers would ignore
them.
It was an error if a progression took a step big enough to skip more than the next milestone.
Progression handlers now keep the internal step
field within [0, max_steps] in case of a too big progression step is
taken.
Progression updates received after progression handler is finished would keep increasing the internal step field.
consume_progression to
muffleProgression to align with restarts
muffleMessage and muffleWarning in base
R.Add a plyr-compatible “progress bar” named
progress_progressr().
Add option progressr.clear.
Visual progression handler will now always render the complete
update state when clear is FALSE.
Now progression handlers ignore a re-signaled
progression condition if it has already been processed
previously.
Now each progression condition holds unique
identifiers for the R session and for the progressor that produced the
condition. It also contains an unique index per progressor that is
incremented whenever a new progression condition is
created.
First decent prototype of this package and the idea behind it.
Make auto_done = TRUE the default.
Add argument auto_done to automatically have
progress updates also signal “done” as soon as the last step has been
reached.
Made amount the first argument of progressors to
avoid having to specify it by name if progressing with an amount than
the default amount = 1.0.
Add argument clear to control whether progress
reporter should clear its output upon completion. The default is to do
this, where supported.
Add progress update handler based on
pbmcapply::progressBar().
Each achieved step is now timestamped.
Add option progressr.debug.
Add intrusiveness parameter that specifies how
intrusive/disruptive a certain progress reporter is. For instance, an
auditory reporter is relatively more disruptive than a visual progress
bar part of the status bar.
Simplified the API for creating new types of progress reporters.
Add progressor().
Add progress_aggregator().
Add progress update handlers based on
utils::txtProgressBar(),
tcltk::tkProgressBar(), cat("\a"),
progress::progress_bar(), beepr::beep(), and
notifier::notify().
Add with_progress().
Add options progressr.handlers for settings default
progress handlers.
Add progressr.times for controlling the number of
times progress updates are rendered.
Add progressr.interval for controlling the minimum
number of seconds that needs to elapse before reporting on the next
update.
Add progress() to create and signal
progression condition.
Add progression() to create progression
condition.