Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect registered progress handler #155

Open
martinju opened this issue Jan 31, 2023 · 4 comments
Open

Detect registered progress handler #155

martinju opened this issue Jan 31, 2023 · 4 comments
Labels
question Further information is requested

Comments

@martinju
Copy link

Hi

Say I have a function foo() which contains code displaying a progress bar with progressr.
Is there a simple way to detect whether either a global handler is registered in the current session, or whether foo() is wrapped within with_progress such that foo() will display a progress bar in my console?

Thanks!

@HenrikBengtsson HenrikBengtsson added the question Further information is requested label Feb 2, 2023
@HenrikBengtsson
Copy link
Owner

Hello.

Is there a simple way to detect whether either a global handler is registered in the current session,

handlers(global = NA) will return TRUE if there's one registered, otherwise FALSE.

or whether foo() is wrapped within with_progress

No, I don't think that's possible. To generalize your question, what you're after is a way to see if it's possible to detect, from foo(), that there is a handler for conditions of class some_handler the following call:

withCallingHandlers({
  foo()
}, some_handler = function(cond) {
  ...
})

I don't think that's possible in R, but I'm not 100% sure. If you could, please reach out on R-devel and ask about this - it could be an interesting feature to have in R.

In progressr, I could of course have with_progress() to temporarily set an internal flag, or an R option, that can be queried, e.g. has_progressr_handlers(). But, before thinking about that ...

such that foo() will display a progress bar in my console?

What are you really trying to achieve here? Note, even if you could know that there are progression handlers actively "listening", you would not know how they report on the progress. For example, handlers("beep") would not "display a progress bar in my console". There are several other handlers that render progress elsewhere (and more to come).

@martinju
Copy link
Author

martinju commented Feb 3, 2023

handlers(global = NA) will return TRUE if there's one registered, otherwise FALSE.

Thanks, that solves my problem assuming everyone uses the global option (which may not be a reasonable assumption).

If you could, please reach out on R-devel and ask about this - it could be an interesting feature to have in R.

I'll try to see if I can make that happen.

In progressr, I could of course have with_progress() to temporarily set an internal flag, or an R option, that can be queried, e.g. has_progressr_handlers(). But, before thinking about that ...

I think that would be very useful for my use case, see below.

What are you really trying to achieve here?

Short story: I want to set different default behavior in a function depending on whether progress handler is enabled or not.

Long story: My use case is a function that splits a potentially memory hungry task into smaller subtasks which are handled separately, and progress is reported for every completed subtask via progressr.
The task splitting reduces the memory consumption significantly, at the cost of an increase in the computation time.

With smaller dimensional data input to the function, memory consumption is not an issue, but the computation time still increases. These cases can be identified based on the input. In these cases, the only reason for doing the splitting is if the user wants to display the computation progress. If the user has not registered a progress handler, it would be preferable to not split the tasks to save some computation time.

So, if I could detect whether the user has enabled progress reporting (of any kind), I can set the default behavior to do task splitting when it is enabled, and disable the task splitting if progress reporting is not enabled by the user.

@HenrikBengtsson
Copy link
Owner

So, if I could detect whether the user has enabled progress reporting (of any kind), I can set the default behavior to do task splitting when it is enabled, and disable the task splitting if progress reporting is not enabled by the user.

I strongly recommend against this. The user might have enabled the global progress handler for other reasons that are unrelated to your package and your function. It's important to always remember that our packages and functions can be used in contexts that we as developers cannot predict or know why and when. Some developers use similar things like if (requireNamespace("foo")) { do this } else { otherwise that }. That introduces a non-deterministic behavior and a major surprise for the end-user; that foo package might have been installed for other reasons.

@martinju
Copy link
Author

martinju commented Feb 6, 2023

I highly value your recommendations on this.
However, I don't quite understand the big issue with my suggested approach.
Based on the input arguments to foo(), I am already setting default values for internal parameters related to computation speed/memory usage (within the function call to foo() only).
The output of the function foo() is exactly the same regardless of how I set these internal parameters.

If a progress handler is enabled, the 'visual behavior' of the call to foo() changes since a progress bar is displayed (or rendered elsewhere).
Now, I also want the computation speed/memory usage (of the call to foo() only) to depend on whether the progress handler is enabled.

The behavior of other functions, packages and global parameters are not changed depending on whether the package with the function foo() is installed/loaded or not.

It would be very helpful if you could elaborate on your view related to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants