瀏覽代碼

Plumber API for R (#7378)

* init commit

* db tests init

* wip:API work

* empty case and text case handled

* fortunes running

* cleaned fortunes

* updates init

* read fix

* plumber Readme added"

* removed unnecessary files

Co-authored-by: mozin <[email protected]>
Emil Mahler Larsen 3 年之前
父節點
當前提交
dc56862ccf

+ 18 - 0
frameworks/R/plumber/README.md

@@ -0,0 +1,18 @@
+# [Plumber](https://www.rplumber.io/) Benchmark Test
+
+The information below is specific to Plumber. For further guidance,
+review the [documentation](https://github.com/TechEmpower/FrameworkBenchmarks/wiki).
+
+This is the R Plumber portion of a [benchmarking tests suite](../../)
+comparing a variety of frameworks.
+
+All test implementations are located within a single file
+([plumber.R](plumber.R)).
+
+## Description
+
+Plumber
+
+### Database
+
+PostgresQL 

+ 30 - 0
frameworks/R/plumber/benchmark_config.json

@@ -0,0 +1,30 @@
+{
+  "framework": "plumber",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "query_url": "/query?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "postgres",
+        "framework": "Plumber",
+        "language": "R",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Plumber",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 19 - 0
frameworks/R/plumber/config.toml

@@ -0,0 +1,19 @@
+[framework]
+name = "plumber"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "None"
+webserver = "None"
+versus = "None"

+ 5 - 0
frameworks/R/plumber/deploy_plumber.R

@@ -0,0 +1,5 @@
+library(plumber)
+
+r <- plumber::plumb('plumber.R')
+
+r$run(port = 8080, host = '0.0.0.0')

+ 118 - 0
frameworks/R/plumber/plumber.R

@@ -0,0 +1,118 @@
+library(plumber)
+library(dplyr)
+library(DBI)
+
+
+READ_ROW_SQL_BASE = 'SELECT "randomnumber", "id" FROM "world" WHERE id = '
+WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
+
+db_con <- dbConnect(RPostgres::Postgres(), dbname = "hello_world", host="tfb-database", port=5432, user="benchmarkdbuser", password="benchmarkdbpass")
+
+
+get_num_queries <- function(queries){
+  query_count <- 1
+  query_count <- as.numeric(queries)
+  if(is.na(query_count)) query_count <- 1
+  if(query_count < 1) return(1)
+  if(query_count > 500) return(500)
+  return(query_count)
+}
+
+
+#* @get /query
+#* @param queries
+#* @serializer json
+function(req, res, queries = NULL) {
+  res$headers$Server <- "example"
+  if(is.null(queries)) queries <- 1
+  num_queries = get_num_queries(queries)
+  row_ids = sample.int(10000, num_queries)
+
+  output_list <- list()
+  for(row_id in row_ids){
+    # number = dbFetch(dbSendQuery(db_con, paste0(READ_ROW_SQL_BASE, row_id)))
+    number = dbGetQuery(db_con, paste0(READ_ROW_SQL_BASE, row_id))
+
+    output_list <- c(output_list, list(list('id' = row_id, 'randomNumber'= number$randomnumber)))
+  }
+  # print(jsonlite::toJSON(plyr::ldply(output_list, as.data.frame)))
+  plyr::ldply(output_list, as.data.frame)
+}
+
+
+#* @get /updates
+#* @param queries
+#* @serializer json
+function(req, res, queries = NULL) {
+  res$headers$Server <- "example"
+  if(is.null(queries)) queries <- 1
+  num_queries = get_num_queries(queries)
+  row_ids = sample.int(10000, num_queries)
+
+  output_list <- list()
+  for(row_id in row_ids){
+    new_random_number <- sample.int(10000, 1)
+    number = dbGetQuery(db_con, paste0(READ_ROW_SQL_BASE, row_id))
+    dbExecute(db_con, paste0('UPDATE "world" SET "randomnumber"=', new_random_number, ' WHERE id=', row_id))
+    output_list <- c(output_list, list(list('id' = row_id, 'randomNumber'= new_random_number)))
+  }
+
+  plyr::ldply(output_list, as.data.frame)
+}
+
+
+#* @get /fortunes
+#* @serializer html
+function(req, res) {
+  res$headers$Server <- "example"
+
+  fortunes_result <- dbGetQuery(db_con, 'SELECT * FROM Fortune')
+  fortunes_df <- as.data.frame(fortunes_result)
+  fortunes_df <- rbind(fortunes_df, data.frame(id = 0, message = 'Additional fortune added at request time.'))
+  fortunes_df <- fortunes_df[order(fortunes_df$message), ]
+  output_string <- "<!doctype html>
+  <html>
+  <head>
+  <title>Fortunes</title>
+  </head>
+  <body>
+  <table>
+  <tr><th>id</th><th>message</th></tr>"
+
+  for(i in 1:nrow(fortunes_df)){
+    output_string <- paste0(output_string, paste0("<tr><td>", fortunes_df[i, 'id'],
+     "</td><td>", fortunes_df[i, 'message'] %>% stringr::str_replace_all("<","&lt;") %>% stringr::str_replace_all(">","&gt;"), "</td></tr>"))
+  }
+  paste0(output_string , "</table>
+  </body>
+  </html>")
+}
+
+
+#* @get /json
+#* @serializer unboxedJSON
+function(req, res) {
+  res$headers$Server <- "example"
+  list('message'= 'Hello, world!')
+}
+
+#* @get /plaintext
+#* @serializer text
+function(req, res) {
+  db_con <- dbConnect(RPostgres::Postgres(), dbname = "hello_world", host="tfb-database", port=5432, user="benchmarkdbuser", password="benchmarkdbpass")
+  res$headers$Server <- "example"
+  'Hello, World!'
+}
+
+
+#* @get /db
+#* @serializer unboxedJSON
+function(req, res) {
+  res$headers$Server <- "example"
+  row_id = sample.int(10000, 1)
+
+  # number = dbFetch(dbSendQuery(db_con, paste0(READ_ROW_SQL_BASE, row_id)))
+  number = dbGetQuery(db_con, paste0(READ_ROW_SQL_BASE, row_id))
+
+  list('id' = row_id, 'randomNumber'= number$randomnumber)
+}

+ 15 - 0
frameworks/R/plumber/plumber.dockerfile

@@ -0,0 +1,15 @@
+FROM rstudio/plumber
+
+RUN apt-get update
+
+RUN apt install postgresql postgresql-contrib -y
+
+RUN R -e "install.packages(c('DBI', 'RPostgres', 'plyr', 'dplyr', 'stringr'))"
+
+ADD ./ /plumber
+
+WORKDIR /plumber
+
+EXPOSE 8080
+
+CMD ["deploy_plumber.R"]