diff --git a/Dockerfile b/Dockerfile index 0753e38..3322a5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN Rscript -e "install.packages('pak', repos = sprintf('https://r-lib.github.io RUN Rscript -e "pak::pkg_install('rstudio/plumber@main')" # install required R packages -RUN Rscript -e "pak::pkg_install(c('logger','tictoc', 'fs', 'promises', 'future'))" +RUN Rscript -e "pak::pkg_install(c('logger','tictoc', 'fs', 'promises', 'future', 'fastmap'))" # install testing packages RUN Rscript -e "pak::pkg_install(c('testthat', 'httr'))" diff --git a/helpers/logging.R b/helpers/logging.R index 4b9fefc..c1ef0dc 100644 --- a/helpers/logging.R +++ b/helpers/logging.R @@ -6,10 +6,10 @@ log_dir <- "logs" if (!fs::dir_exists(log_dir)) fs::dir_create(log_dir) log_appender(appender_tee(tempfile(paste0("plumber_", Sys.time(), "_"), log_dir, ".log"))) -convert_empty <- function(string) { - if (string == "") { - return("-") - } +# transoform empty value to - +convert_empty <- function(string = "") { + if (is.null(string)) return("-") + if (string == "") return("-") return(string) } @@ -19,5 +19,14 @@ pre_route_logging <- function(req) { post_route_logging <- function(req, res) { end <- tictoc::toc(quiet = TRUE) # nolint - log_info('{convert_empty(req$REMOTE_ADDR)} "{convert_empty(req$HTTP_USER_AGENT)}" {convert_empty(req$HTTP_HOST)} {convert_empty(req$REQUEST_METHOD)} {convert_empty(end$msg)} {convert_empty(res$status)} {round(end$toc - end$tic, digits = getOption("digits", 5))}') # nolint + + log_info(sprintf('%s "%s" %s %s %s %s %s', + convert_empty(req$REMOTE_ADDR), + convert_empty(req$HTTP_USER_AGENT), + convert_empty(req$HTTP_HOST), + convert_empty(req$REQUEST_METHOD), + convert_empty(end$msg), + convert_empty(res$status), + round(end$toc - end$tic, digits = getOption("digits", 5)) + )) # nolint } \ No newline at end of file diff --git a/helpers/parallel.R b/helpers/parallel.R index 5d395d4..d6e0073 100644 --- a/helpers/parallel.R +++ b/helpers/parallel.R @@ -1,4 +1,5 @@ library(future) +library(promises) future::plan(future::multisession(workers = WORKERS)) diff --git a/readme.md b/readme.md index fa8015a..0d45fdf 100644 --- a/readme.md +++ b/readme.md @@ -12,15 +12,15 @@ This repository is a boilerplate to setup a new project with R plumber. You can | Dynamic Filter/Miiddleware | ✅ | Add custom filter / middleware each mounted route from `routes` dir | | Request Validation | ✅ | Simple validation mechanism to check incoming request from request body / params, such as required fields, check type (number, boolean, array), check the value in given array, etc. | | Docker | ✅ | Simplifying apps with docker, for better development, deployment, dependencies management, and scaling | -| Parallel Processing | Not Yet | R only run a request at a time, make it process in parallel with `promises` and `future` packages. | +| Parallel Processing | ✅ | R only run a request at a time, make it process in parallel with `promises` and `future` packages. | | Testing | ✅ | Testing for endpoints / routes and helper functions with `testthat` and `httr` packages, also use Docker and docker-compose for setting up automated testing. For running in CI / CD, an example also provided. | This template comes with built in Environment Variables that you can edit when running it. -| ENV | Default | Description | -| -------- | :---------: | ---------------------------------------------------------------------------------------------- | -| `HOST` | `127.0.0.1` | Host to run Rplumber, use `0.0.0.0` when running it in Docker | -| `PORT` | `8000` | Which port Rplumber will run | +| ENV | Default | Description | +| --------- | :---------: | ---------------------------------------------------------------------------------------------- | +| `HOST` | `127.0.0.1` | Host to run Rplumber, use `0.0.0.0` when running it in Docker | +| `PORT` | `8000` | Which port Rplumber will run | | `WORKERS` | `3` | Number of worker (Rsession) to run parallel processing in Rplumber (including the main worker) | ## How to use it