library(knitr)

knitr::opts_chunk$set(collapse = TRUE, comment = "#>")

Deferred and Remote

In the Introduction vignette we explain the steps to create a simple deferred function wrapper. Here we will show how it can be combined with other packages to implement a simple RPC mechanism.

Preparing the Wrapper

Unlike in the Introduction, to avoid clouding the message, this time we will work with a much simplified example. Here's the function we want to run in a remote R session:

fun <- function(x, y) x ^ y

Now we need to wrap it using defer(). Rrunning the wrapper is still straightforward.

library(defer)

deferred_fun <- defer(fun)
deferred_fun(9, 2)

Because it is easier to run an argument-less function, our first step will be to augment our deferred function wrapper with a value for both of its arguments.

deferred_fun <- augment(deferred_fun, x = 7, y = 3)

Now we can call deferred_fun() completely ommitting arguments (see ?defer::augment for more details).

deferred_fun()

OpenCPU

Our first example will be OpenCPU. We will also need two other packages: jsonlite to serialize the wrapper and httr to talk to OpenCPU's HTTP-based API. jsonlite is a prerequisite of opencpu so we can be sure it will be available.

Making the Call

With OpenCPU we can run any R function available in any of the packages installed on the remote R server. OpenCPU also knows how to handle an uploaded file, thus we will call base::source() and send a very simple script, local_script_path, as its argument. We will call a public OpenCPU server, cloud.opencpu.org.

library(httr)
library(jsonlite)

public_opencpu_url <- "https://cloud.opencpu.org/ocpu/library/base/R/source/print"
local_script_path <- tempfile(fileext = ".R")

Here is how we invoke the remote OpenCPU server throgh httr:

http_result <- httr::POST(public_opencpu_url,
                          body = list(file = upload_file(local_script_path)))

The Script

The script contains deferred_fun serialized into a base64-encoded string. It instructs the remote R session to decode the string, unserialize the wrapper and then run it in that remote R session.

serialized_wrapper <- jsonlite::base64_enc(serialize(deferred_fun, NULL))
cat(paste0("bytes <- unserialize(jsonlite::base64_dec('", serialized_wrapper, "'))\n",
           "deserialized()\n"),
    file = local_script_path)

Running the OpenCPU Example

Now that everything is set, we can run the HTTP call and collect the result.

http_result <- httr::POST(public_opencpu_url,
                          body = list(file = upload_file(local_script_path)))
content(http_result, 'text')

source() returns a list with two elements: value is the value of the last statement in the file - which is 7 to the power of 3, as expected; visible is an attribute that tells us if value was intended to be printed out.

foreach

Rserve

SparkR

(planned) extension for dplyr::do



lbartnik/defer documentation built on May 20, 2019, 8:27 p.m.