Skip to content

Commit

Permalink
Merge branch 'master' into mnt_updates
Browse files Browse the repository at this point in the history
* master:
  Quote the version number in Dockerfile (#751)
  Do not use `plan(multiprocess)`. Instead, use `plan(multisession)` (#747)
  Default res headers to named list instead of list (#745)
  Add stage debugging section in Tips&Tricks (#741)
  Switch `Plumber$print()` wording to use magrittr api (#742)
  • Loading branch information
schloerke committed Jan 5, 2021
2 parents 53607d2 + 1d11c9e commit 04f1dbb
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches:
- "master"
- "docker/**"
- "docker**"
schedule:
- cron: '0 0 1 * *' # first of every month

Expand All @@ -26,7 +26,7 @@ jobs:
# always overwrite the latest version with the CRAN version
tags: "v1.0.0,latest"
ref: "v1.0.0"

# always rebuild legacy to pick up newer R library builds
- name: "v0.4.6"
tags: "v0.4.6"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ARG PLUMBER_REF=master
RUN Rscript -e "remotes::install_github('rstudio/plumber@${PLUMBER_REF}')"

EXPOSE 8000
ENTRYPOINT ["R", "-e", "pr <- plumber::plumb(rev(commandArgs())[1]); args <- list(host = '0.0.0.0', port = 8000); if (packageVersion('plumber') >= 1.0.0) { pr$setDocs(TRUE) } else { args$swagger <- TRUE }; do.call(pr$run, args)"]
ENTRYPOINT ["R", "-e", "pr <- plumber::plumb(rev(commandArgs())[1]); args <- list(host = '0.0.0.0', port = 8000); if (packageVersion('plumber') >= '1.0.0') { pr$setDocs(TRUE) } else { args$swagger <- TRUE }; do.call(pr$run, args)"]

# Copy installed example to default file at ~/plumber.R
ARG ENTRYPOINT_FILE=/usr/local/lib/R/site-library/plumber/plumber/04-mean-sum/plumber.R
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ plumber 1.0.0.9999 Development version

### Bug fixes

* Fixed bug where `httpuv` would return a status of `500` with body `An exception occurred` if no headers were set on the response object. (#745)

* Fixed bug where all `pr_*()` returned invisibly. Now all `pr_*()` methods will print the router if displayed in the console. (#740)

* Ignore regular comments in block parsing (@meztez #718)
Expand All @@ -41,6 +43,8 @@ plumber 1.0.0.9999 Development version

* Plumber will now display a circular reference if one is found while printing. (#738)

* Changed `future::plan()` from `multiprocess` to `multisession` in example API `14-future` as "Strategy 'multiprocess' is deprecated in future (>= 1.20.0)". (#747)


plumber 1.0.0
--------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion R/plumber-response.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PlumberResponse <- R6Class(
},
status = 200L,
body = NULL,
headers = list(),
headers = stats::setNames(list(), character()),
serializer = NULL,
setHeader = function(name, value){
he <- list()
Expand Down
2 changes: 1 addition & 1 deletion R/plumber.R
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ Plumber <- R6Class(
as.character(length(self$mounts)), " sub-router", ifelse(length(self$mounts) == 1, "", "s"),".\n", sep=""))

if(topLevel){
cat(prefix, crayon::silver("# Call run() on this object to start the API.\n"), sep="")
cat(prefix, crayon::silver("# Use `pr_run()` on this object to start the API.\n"), sep="")
}

# Filters
Expand Down
4 changes: 2 additions & 2 deletions inst/plumber/14-future/plumber.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
library(promises)
library(future)

future::plan("multiprocess") # use all available cores
# future::plan(future::multiprocess(workers = 2)) # only two cores
future::plan("multisession") # a worker for each core
# future::plan(future::multisession(workers = 2)) # only two workers

# Quick manual test:
# Within 10 seconds...
Expand Down
4 changes: 2 additions & 2 deletions inst/plumber/14-future/test-future.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ cat(readLines(log_file), sep = "\n")
}))
# --------------------------

## Sample output using future::plan(future::multiprocess(workers = 2)) # only two cores
## Sample output using future::plan(future::multisession(workers = 2)) # only two workers
# --START route requests
# "/sync; 2019-10-07 13:11:06; pid:82424" - 1
# "/sync; 2019-10-07 13:11:07; pid:82424" - 3
Expand All @@ -88,7 +88,7 @@ cat(readLines(log_file), sep = "\n")

# --------------------------

## Sample output using future::plan("multiprocess") # use all available cores
## Sample output using future::plan("multisession") # a worker for each core
# --START route requests
# "/sync; 2019-10-07 13:16:22; pid:82424" - 1
# "/sync; 2019-10-07 13:16:23; pid:82424" - 3
Expand Down
6 changes: 3 additions & 3 deletions tests/testthat/test-plumber-print.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test_that("prints correctly", {

expected_output <- c(
"# Plumber router with 2 endpoints, 4 filters, and 2 sub-routers.",
"# Call run() on this object to start the API.",
"# Use `pr_run()` on this object to start the API.",
"├──[queryString]",
"├──[body]",
"├──[cookieParser]",
Expand All @@ -43,7 +43,7 @@ test_that("prints correctly", {

expected_output2 <- c(
"# Plumber router with 1 endpoint, 4 filters, and 0 sub-routers.",
"# Call run() on this object to start the API.",
"# Use `pr_run()` on this object to start the API.",
"├──[queryString]",
"├──[body]",
"├──[cookieParser]",
Expand Down Expand Up @@ -74,7 +74,7 @@ test_that("prints correctly", {

expected_output <- c(
"# Plumber router with 0 endpoints, 4 filters, and 1 sub-router.",
"# Call run() on this object to start the API.",
"# Use `pr_run()` on this object to start the API.",
"├──[queryString]",
"├──[body]",
"├──[cookieParser]",
Expand Down
66 changes: 66 additions & 0 deletions vignettes/tips-and-tricks.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,72 @@ Most programmers first approach debugging by adding print statements to their co

This approach is equally viable with Plumber. When developing your Plumber API in an interactive environment, this debugging output will be logged to the same terminal where you called `run()` on your API. In a non-interactive production environment, these messages will be included in the API server logs for later inspection.

### Router Stage Debugging

Similar to print debugging, we can output what plumber knows at each stage of the processing pipeline. You can do this by adding [hooks](./programmatic-usage.html#router-hooks) to two key stages: `"postroute"` and `"postserialize"`.

For example, we can add these lines to our `plumber.R` file:

```r
#* @plumber
function(pr) {
pr %>%
pr_hook("postroute", function(req, value) {
# Print stage information
str(list(
stage = "postroute",
type = req$REQUEST_METHOD,
path = req$PATH_INFO,
value = value
))
# Must return the `value` since we took one in
value
}) %>%
pr_hook("postserialize", function(req, value) {
# Print stage information
str(list(
stage = "postserialize",
type = req$REQUEST_METHOD,
path = req$PATH_INFO,
value = value
))
# Must return the `value` since we took one in
value
})
}
```

If we were to execute a `GET` request on `/stage_debug`

```r
#* @get /stage_debug
function(req, res) {
return(42)
}
```
, we would expect to see output like:

```
List of 4
$ stage: chr "postroute"
$ type : chr "GET"
$ path : chr "/stage_debug"
$ value: num 42
List of 4
$ stage: chr "postserialize"
$ type : chr "GET"
$ path : chr "/stage_debug"
$ value:List of 3
..$ status : int 200
..$ headers:List of 1
.. ..$ Content-Type: chr "application/json"
..$ body : 'json' chr "[42]"
```

This output shows that the route `/stage_debug` calculated the value `42` and that the value was serialized using json. We should expect to see that the received response has a status of `200` and the body containing JSON matching `[42]`.



### Interactive Debugging

Print debugging is an obvious starting point, but most developers eventually wish for something more powerful. In R, this capacity is built in to the `browser()` function. If you're unfamiliar, `browser()` pauses the execution of some function and gives you an interactive session in which you can inspect the current value of internal variables or even proceed through your function one statement at a time.
Expand Down

0 comments on commit 04f1dbb

Please sign in to comment.