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

Expand user API for all Service operations #14

Merged
merged 26 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d21db24
Feat: add helper to check object type
mihaiconstantin Feb 23, 2023
52fcff5
Feat: add type checks for user API functions
mihaiconstantin Feb 24, 2023
6cd89c9
Refactor: set `backend = NULL` by default in `par_sapply`
mihaiconstantin Feb 24, 2023
829730a
Docs: update documentation for `stop_backend`
mihaiconstantin Feb 24, 2023
ded31d1
Docs: update documentation for `par_sapply`
mihaiconstantin Feb 24, 2023
983acd7
Feat: add `clear` function to clean backends
mihaiconstantin Feb 24, 2023
c65918c
Feat: add `export` function to export objects to backends
mihaiconstantin Feb 24, 2023
173c904
Feat: add `peek` function to list backend variables
mihaiconstantin Feb 24, 2023
1c11e48
Feat: add `evaluate` function to evaluate expressions on backends
mihaiconstantin Feb 24, 2023
30e076d
Fix: use `.GlobalEnv` as fallback in `export` methods
mihaiconstantin Feb 27, 2023
2d90bcd
Docs: update `@examples` for `start_backend` function
mihaiconstantin Feb 27, 2023
c3e7e46
Docs: reuse `start_backend` `@examples` in `stop_backend`
mihaiconstantin Feb 27, 2023
4de4119
Docs: update references in `@seealso` sections
mihaiconstantin Feb 27, 2023
21cc6c3
Docs: update `@details` for `stop_backend`
mihaiconstantin Feb 27, 2023
6df988b
Docs: add documentation for `clear` function
mihaiconstantin Feb 27, 2023
bb98757
Docs: add documentation for `peek` function
mihaiconstantin Feb 27, 2023
ab4f4d5
Docs: add documentation for `export` function
mihaiconstantin Feb 27, 2023
c02cf35
Docs: add documentation for `evaluate` function
mihaiconstantin Feb 27, 2023
8328b7d
Style: add missing new line in `exports.R`
mihaiconstantin Feb 27, 2023
c2ecb29
Docs: update `@seealso` for `par_sapply`
mihaiconstantin Feb 27, 2023
6bdd66c
Docs: update title for `export` function
mihaiconstantin Feb 27, 2023
409ef5b
Docs: regenerate `.Rd` files
mihaiconstantin Feb 27, 2023
3d76170
Docs: add changes to `NEWS`
mihaiconstantin Feb 27, 2023
a55327b
Docs: add missing topics to website reference
mihaiconstantin Feb 27, 2023
ad67b17
Docs: add mentions to additional exported wrappers
mihaiconstantin Feb 27, 2023
029d56c
Docs: override `pkgdown` styles for exported wrappers table
mihaiconstantin Feb 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ export(Specification)
export(SyncBackend)
export(TaskState)
export(Warning)
export(clear)
export(configure_bar)
export(evaluate)
export(export)
export(get_option)
export(make_logo)
export(par_sapply)
export(peek)
export(set_default_options)
export(set_option)
export(start_backend)
Expand Down
35 changes: 34 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# Development

## Added
- Add new exported wrappers to the `pkgdown` reference section.
- Add several exported wrappers to the user API:
- `clear`: to clean a provided backend instance.
- `export`: to export variables from a give environment to the `.GlobalEnv` of
the backend instance.
- `peek`: to list the variables names available on the backend instance.
- `evaluate`: to evaluate arbitrary expressions on the backend instance.
- Add type checks for the exported functions (i.e., the user API).
- Add helper method for checking and validating the type of an object. The
`Helper$check_object_type` method checks if the type of an object matches an
expected type. If that is not the case, the helper throws an error (i.e.,
`Exception$type_not_assignable`).

## Changed
- Add `.scss` styles to override the table column width for the exported
wrappers table in the `pkgdown` website.
- Update `README` and package documentation to mention new exported wrappers.
- Update order of topics for website reference section generated via `pkgdown`.
- Update `roxygen2` `@examples` for exported wrappers. The code for the examples
is located in the documentation for the `start_backend` function. All other
exported wrappers (i.e., `clear`, `export`, `peek`, `evaluate`, and
`par_sapply`) inherit the `@examples` section from `start_backend`.
- Update references in `@seealso` documentation sections.
- Change `backend` argument of `par_sapply` to `backend = NULL`. This implies,
that `par_sapply` without a backend behaves identically to `base::sapply`.

## Fixed
- Update `export` method to use the `.GlobalEnv` as fallback when exporting
variables.

# parabar 0.9.4

## Added
Expand All @@ -16,7 +49,7 @@
- Ensure the examples in `ProgressBar` use `wait = TRUE` when fetching the
output.
- Fix bug in the `evaluate` backend operation. The expression passed to
`evaluate` was not correctly passed along the function chain to
`evaluate` was not correctly passed down the function chain to
`parallel::clusterCall`. See [this
question](https://stackoverflow.com/q/75543796/5252007) on `StackOverflow` for
clarifications. Closes
Expand Down
4 changes: 2 additions & 2 deletions R/AsyncBackend.R
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@
#' backend$active
#'
#' @seealso
#' [`parabar::Service`], [`parabar::Backend`], [`parabar::SyncBackend`], and
#' [`parabar::ProgressDecorator`].
#' [`parabar::Service`], [`parabar::Backend`], [`parabar::SyncBackend`],
#' [`parabar::ProgressDecorator`], and [`parabar::TaskState`].
#'
#' @export
AsyncBackend <- R6::R6Class("AsyncBackend",
Expand Down
13 changes: 13 additions & 0 deletions R/Helper.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#' \item{\code{Helper$get_class_name()}}{Helper for getting the class of a given object.}
#' \item{\code{Helper$get_option()}}{Get package option, or corresponding default value.}
#' \item{\code{Helper$set_option()}}{Set package option.}
#' \item{\code{Helper$check_object_type()}}{Check the type of a given object.}
#' }
#'
#' @export
Expand Down Expand Up @@ -55,3 +56,15 @@ Helper$set_option <- function(option, value) {
# Set the `Options` instance in the global options.
options(parabar = options)
}

# Helper for performing a type check on a given object.
Helper$check_object_type <- function(object, expected_type) {
# Get object class name.
type <- Helper$get_class_name(object)

# If the object does not inherit from the expected type.
if (!inherits(object, expected_type)) {
# Throw incorrect type error.
Exception$type_not_assignable(type, expected_type)
}
}
4 changes: 2 additions & 2 deletions R/SyncBackend.R
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ SyncBackend <- R6::R6Class("SyncBackend",
export = function(variables, environment) {
# If no environment is provided.
if (missing(environment)) {
# Use the caller's environment where the variables are defined.
environment <- parent.frame()
# Use the global environment.
environment <- .GlobalEnv
}

# Export and return the output.
Expand Down
60 changes: 59 additions & 1 deletion R/exports.r
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ start_backend <- function(cores, cluster_type = "psock", backend_type = "async")
#' @template stop-backend
#' @export
stop_backend <- function(backend) {
# Check the type.
Helper$check_object_type(backend, "Backend")

# Stop the backend
backend$stop()

Expand All @@ -102,16 +105,71 @@ stop_backend <- function(backend) {
}


#' @template clear
#' @export
clear <- function(backend) {
# Check the type.
Helper$check_object_type(backend, "Backend")

# Peek the backend.
backend$clear()
}


#' @template peek
#' @export
peek <- function(backend) {
# Check the type.
Helper$check_object_type(backend, "Backend")

# Peek the backend..
backend$peek()
}


#' @template export
#' @export
export <- function(backend, variables, environment) {
# Check the type.
Helper$check_object_type(backend, "Backend")

# Export variables.
backend$export(variables, environment)
}


#' @template evaluate
#' @export
evaluate <- function(backend, expression) {
# Check the type.
Helper$check_object_type(backend, "Backend")

# Capture the expression.
capture <- substitute(expression)

# Prepare the call.
capture_call <- bquote(backend$evaluate(.(capture)))

# Perform the call.
eval(capture_call)
}


#' @template par-sapply
#' @export
par_sapply <- function(backend, x, fun, ...) {
par_sapply <- function(backend = NULL, x, fun, ...) {
# If no backend is provided.
if (is.null(backend)) {
# Then use the built in, non-parallel `base::sapply`.
output <- base::sapply(X = x, FUN = fun, ...)

# Return results.
return(output)

# Otherwise, if a backend is provided.
} else {
# Check the type.
Helper$check_object_type(backend, "Backend")
}

# Get user warning settings.
Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ consists of the following steps:
3. Stop the backend.

Optionally, you can also configure the progress bar if the backend created
supports progress tracking.
supports progress tracking, or perform additional operations on the backend.

#### Synchronous Backend
The simplest, and perhaps least interesting, way to use
Expand Down Expand Up @@ -239,6 +239,26 @@ results <- par_sapply(backend = NULL, 1:300, function(x) {
})
```

#### Additional Operations
As indicated above, the general workflow consists of starting a backend,
executing a task in parallel, and stopping the backend. However, there are
additional operations that can be performed on a backend (i.e., see
_**Developers**_ section). The table below lists all available operations that
can be performed on a backend.

| Operation | Description |
| :--------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- |
| <code><a href="https://parabar.mihaiconstantin.com/reference/start_backend.html">start_backend(backend)</a></code> | Start a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/stop_backend.html">stop_backend(backend)</a></code> | Stop a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/clear.html">clear(backend)</a></code> | Remove all objects from a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/peek.html">peek(backend)</a></code> | List the names of the variables on a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/export.html">export(backend, variables, environment)</a></code> | Export objects to a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/evaluate.html">evaluate(backend, expression)</a></code> | Evaluate expressions on a backend. |
| <code><a href="https://parabar.mihaiconstantin.com/reference/par_sapply.html">par_sapply(backend, x, fun)</a></code> | Run tasks in parallel on a backend. |

Check the documentation corresponding to each operation for more information and
examples.

### Developers
[`parabar`](https://parabar.mihaiconstantin.com) provides a rich API for
developers who want to use the package in their own projects.
Expand Down
29 changes: 27 additions & 2 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,36 @@ reference:
- subtitle: Main Functions
desc: Functions intended for use in interactive `R` sessions.
- contents:
- matches("start_|stop_|par_|configure_|set_|get_")
- start_backend
- stop_backend
- export
- peek
- clear
- evaluate
- par_sapply
- configure_bar
- matches("get_|set_")
- subtitle: Developer Classes
desc: API based on the `R6` class system for package developers.
- contents:
- matches("([A-Z][a-z0-9]+)+")
- Service
- Backend
- SyncBackend
- AsyncBackend
- BackendFactory
- Specification
- Context
- ProgressDecorator
- ContextFactory
- TaskState
- Bar
- BasicBar
- ModernBar
- BarFactory
- Options
- Helper
- Warning
- Exception
- subtitle: Miscellaneous
desc: Very specific functions that may safely be ignored.
- contents:
Expand Down
26 changes: 26 additions & 0 deletions man-roxygen/clear.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#' @title
#' Clear a Backend
#'
#' @description
#' This function can be used to clear a [`backend`][`parabar::Backend`] created
#' by [parabar::start_backend()].
#'
#' @param backend An object of class [`parabar::Backend`] as returned by the
#' [parabar::start_backend()] function.
#'
#' @details
#' This function is a convenience wrapper around the lower-lever API of
#' [`parabar::parabar`] aimed at developers. More specifically, this function
#' calls the [`clear`][`parabar::Service`] method on the provided
#' [`backend`][`parabar::Backend`] instance.
#'
#' @return
#' The function returns void. It throws an error if the value provided for the
#' `backend` argument is not an instance of class [`parabar::Backend`].
#'
#' @inherit start_backend examples
#'
#' @seealso
#' [parabar::start_backend()], [parabar::peek()], [parabar::export()],
#' [parabar::evaluate()], [parabar::configure_bar()], [parabar::par_sapply()],
#' [parabar::stop_backend()], and [`parabar::Service`].
29 changes: 29 additions & 0 deletions man-roxygen/evaluate.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#' @title
#' Evaluate An Expression On The Backend
#'
#' @description
#' This function can be used to evaluate an arbitrary [base::expression()] a
#' [`backend`][`parabar::Backend`] created by [parabar::start_backend()].
#'
#' @param backend An object of class [`parabar::Backend`] as returned by the
#' [parabar::start_backend()] function.
#'
#' @param expression An unquoted expression to evaluate on the backend.
#'
#' @details
#' This function is a convenience wrapper around the lower-lever API of
#' [`parabar::parabar`] aimed at developers. More specifically, this function
#' calls the [`evaluate`][`parabar::Service`] method on the provided
#' [`backend`][`parabar::Backend`] instance.
#'
#' @return
#' This method returns the result of the expression evaluation. It throws an
#' error if the value provided for the `backend` argument is not an instance of
#' class [`parabar::Backend`].
#'
#' @inherit start_backend examples
#'
#' @seealso
#' [parabar::start_backend()], [parabar::peek()], [parabar::export()],
#' [parabar::clear()], [parabar::configure_bar()], [parabar::par_sapply()],
#' [parabar::stop_backend()], and [`parabar::Service`].
32 changes: 32 additions & 0 deletions man-roxygen/export.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#' @title
#' Export Objects To a Backend
#'
#' @description
#' This function can be used to export objects to a
#' [`backend`][`parabar::Backend`] created by [parabar::start_backend()].
#'
#' @param backend An object of class [`parabar::Backend`] as returned by the
#' [parabar::start_backend()] function.
#'
#' @param variables A character vector of variable names to export to the
#' backend.
#'
#' @param environment An environment from which to export the variables. If no
#' environment is provided, the `.GlobalEnv` environment is used.
#'
#' @details
#' This function is a convenience wrapper around the lower-lever API of
#' [`parabar::parabar`] aimed at developers. More specifically, this function
#' calls the [`export`][`parabar::Service`] method on the provided
#' [`backend`][`parabar::Backend`] instance.
#'
#' @return
#' The function returns void. It throws an error if the value provided for the
#' `backend` argument is not an instance of class [`parabar::Backend`].
#'
#' @inherit start_backend examples
#'
#' @seealso
#' [parabar::start_backend()], [parabar::peek()], [parabar::evaluate()],
#' [parabar::clear()], [parabar::configure_bar()], [parabar::par_sapply()],
#' [parabar::stop_backend()], and [`parabar::Service`].
9 changes: 6 additions & 3 deletions man-roxygen/par-sapply.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#' See the **Details** section for more information on how this function works.
#'
#' @param backend An object of class [`parabar::Backend`] as returned by the
#' [parabar::start_backend()] function.
#' [parabar::start_backend()] function. It can also be `NULL` to run the task
#' sequentially via [base::sapply()]. The default value is `NULL`.
#'
#' @param x A vector (i.e., usually of integers) to pass to the `fun` function.
#'
Expand Down Expand Up @@ -92,5 +93,7 @@
#' }
#'
#' @seealso
#' [parabar::start_backend()], [parabar::stop_backend()],
#' [parabar::configure_bar()], [`parabar::Options`]
#' [parabar::start_backend()], [parabar::peek()], [parabar::export()],
#' [parabar::evaluate()], [parabar::clear()], [parabar::configure_bar()],
#' [parabar::stop_backend()], [parabar::set_option()], [parabar::get_option()],
#' [`parabar::Options`], and [`parabar::Service`].
Loading