Stateful Agent
This example shows, how VRPC handles stateful interactions with R.
The example here takes up the ideas as shown in the shiny reactivity example, to demonstrate how these concepts map to VRPC.
Stateful R code to be called remotely
The fundamental idea behind the shiny example is to show that input parameters can be explicitly wired, such that only specific functions are re-evaluated and not simply everything. Shiny calls this concept "reactivity" and technically it does (at least) two things:
Building up dependency chains (a polytree) for functions required to evaluate on a given input change
Caching of last-values-changed to avoid unnecessary re-evaluations
As VRPC does not implement the reactivity wiring in R, but in the client application this leads to the following effect:
Individual tasks can be implemented using individual functions
Caching is naturally done by sharing state between the functions (using variables)
This leads to very simple and clean code:
library("vrpc")
dataset <- NULL
select_dataset <- function(name) {
dataset <<- switch(name,
"rock" = rock,
"pressure" = pressure,
"cars" = cars
)
return(TRUE)
}
get_summary <- function() {
summary(dataset)
}
get_table <- function(obs) {
head(dataset, n = obs)
}
start_vrpc_agent(domain = "public.vrpc")
Note, that the caption
output from the shiny example is entirely skipped here as there is no computation but only re-rendering involved. In VRPC the caption update is accomplished solely on client-side. Shiny needs a roundtrip as rendering is done server-side.
Call R code and manage state
Existing R code is mapped into the Session
class on the remote client-side. All functions preceding the start_vrpc_agent
line are available as static functions of the Session
class and as member functions of Session
class instances.
NOTE
Additionally, the generic
call
function is injected (both statically and as member) which allows calling any other R code.
Within a Session
instance all state is maintained, allowing client code like this:
const { VrpcRemote } = require('vrpc')
if (process.argv.length < 3) {
console.log('Usage: node index.js <agentName>')
process.exit(1)
}
(async () => {
const client = new VrpcRemote({
domain: 'public.vrpc',
agent: process.argv[2]
})
await client.connect()
const proxy = await client.create({
className: 'Session',
instance: 'session1'
})
await proxy.select_dataset('rock')
await proxy.get_table(1) // first line of rock dataset
await proxy.select_dataset('cars')
await proxy.get_table(2) // first two lines of cars dataset
await proxy.get_summary() // summary information of cats dataset
})()
Last updated