Browse Source

Add crystal-radix (#3094)

Mark 7 years ago
parent
commit
51abc1d74e

+ 25 - 2
frameworks/Crystal/crystal/benchmark_config.json

@@ -1,5 +1,5 @@
 {
 {
-  "framework": "crystal-raw",
+  "framework": "crystal",
   "tests": [{
   "tests": [{
     "default": {
     "default": {
       "setup_file": "setup",
       "setup_file": "setup",
@@ -24,7 +24,30 @@
       "display_name": "Crystal",
       "display_name": "Crystal",
       "notes": "",
       "notes": "",
       "versus": "crystal"
       "versus": "crystal"
+    },
+    "radix": {
+      "setup_file": "setup_radix",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "Postgres",
+      "framework": "None",
+      "language": "Crystal",
+      "flavor": "None",
+      "orm": "Raw",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Crystal-radix",
+      "notes": "",
+      "versus": "crystal"
     }
     }
   }]
   }]
 }
 }
-

+ 137 - 0
frameworks/Crystal/crystal/server_radix.cr

@@ -0,0 +1,137 @@
+require "http/server"
+require "json"
+require "pg"
+require "ecr"
+require "radix"
+
+plaintext_handler = ->(context : HTTP::Server::Context) do
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "text/plain"
+  response.print "Hello, World!"
+  return response
+end
+
+json_handler = ->(context : HTTP::Server::Context) do
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "application/json"
+  {message: "Hello, World!"}.to_json(response)
+  return response
+end
+
+db_handler = ->(context : HTTP::Server::Context) do
+  request = context.request
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "application/json"
+  random_world.to_json(response)
+  return response
+end
+
+queries_handler = ->(context : HTTP::Server::Context) do
+  request = context.request
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "application/json"
+
+  JSON.build(response) do |json|
+    json.array do
+      sanitized_query_count(request).times do
+        random_world.to_json(json)
+      end
+    end
+  end
+  return response
+end
+
+fortunes_handler = ->(context : HTTP::Server::Context) do
+  request = context.request
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "text/html; charset=UTF-8"
+
+  data = fortunes
+  additional_fortune = {
+    id:      0,
+    message: "Additional fortune added at request time.",
+  }
+
+  data.push(additional_fortune)
+  data.sort! { |f1, f2| f1[:message] <=> f2[:message] }
+
+  ECR.embed "views/fortunes.ecr", response
+  return response
+end
+
+updates_handler = ->(context : HTTP::Server::Context) do
+  request = context.request
+  response = context.response
+  response.status_code = 200
+  response.headers["Content-Type"] = "application/json"
+
+  JSON.build(response) do |json|
+    json.array do
+      sanitized_query_count(request).times do
+        world = set_world({id: random_world[:id], randomNumber: rand(1..ID_MAXIMUM)})
+        world.to_json(json)
+      end
+    end
+  end
+  return response
+end
+
+tree = Radix::Tree(Proc(HTTP::Server::Context, HTTP::Server::Response)).new
+tree.add "/plaintext", plaintext_handler
+tree.add "/json", json_handler
+tree.add "/db", db_handler
+tree.add "/queries", queries_handler
+tree.add "/fortunes", fortunes_handler
+tree.add "/updates", updates_handler
+
+APPDB = DB.open("postgres://benchmarkdbuser:benchmarkdbpass@#{ENV["DBHOST"]? || "127.0.0.1"}/hello_world")
+ID_MAXIMUM = 10_000
+
+server = HTTP::Server.new("0.0.0.0", 8080) do |context|
+  request = context.request
+  response = context.response
+  response.headers["Server"] = "Crystal"
+  response.headers["Date"] = Time.utc_now.to_s
+
+  result = tree.find(request.path)
+
+  if result.found?
+    result.payload.call(context)
+  else
+    context.response.status_code = 404
+  end
+end
+
+private def random_world
+  id = rand(1..ID_MAXIMUM)
+  random_number = APPDB.query_one("SELECT randomNumber FROM world WHERE id = $1", id, as: Int32)
+  {id: id, randomNumber: random_number}
+end
+
+private def set_world(world)
+  APPDB.exec("UPDATE world SET randomNumber = $1 WHERE id = $2", world[:randomNumber], world[:id])
+  world
+end
+
+private def fortunes
+  data = Array(NamedTuple(id: Int32, message: String)).new
+
+  APPDB.query_each("SELECT id, message FROM Fortune") do |rs|
+    data.push({id: rs.read(Int32), message: rs.read(String)})
+  end
+
+  data
+end
+
+private def sanitized_query_count(request)
+  queries = request.query_params["queries"].as(String)
+  queries = queries.to_i? || 1
+  queries.clamp(1..500)
+end
+
+server.listen(reuse_port: true)

+ 15 - 0
frameworks/Crystal/crystal/setup_radix.sh

@@ -0,0 +1,15 @@
+#!/bin/bash
+
+fw_depends postgresql crystal
+
+shards install
+
+crystal build --release --no-debug server_radix.cr -o server_radix.out
+
+export GC_MARKERS=1
+
+for i in $(seq 1 $(nproc --all)); do
+  ./server_radix.out &
+done
+
+wait

+ 5 - 1
frameworks/Crystal/crystal/shard.lock

@@ -2,9 +2,13 @@ version: 1.0
 shards:
 shards:
   db:
   db:
     github: crystal-lang/crystal-db
     github: crystal-lang/crystal-db
-    version: 0.4.2
+    version: 0.4.3
 
 
   pg:
   pg:
     github: will/crystal-pg
     github: will/crystal-pg
     version: 0.13.3
     version: 0.13.3
 
 
+  radix:
+    github: luislavena/radix
+    version: 0.3.8
+

+ 6 - 1
frameworks/Crystal/crystal/shard.yml

@@ -6,4 +6,9 @@ dependencies:
     github: "will/crystal-pg"
     github: "will/crystal-pg"
     version: "0.13.3"
     version: "0.13.3"
 
 
-license: "MIT"
+  radix:
+    github: luislavena/radix
+    version: 0.3.8
+
+
+license: "MIT"