Browse Source

Feature/added crystal raze (#3818)

* added raze framework

* removed commented code

* added readme

* added reuse_port option

* fix dockerfile

* added missing shard.lock
Carlos Donderis 7 years ago
parent
commit
27eb965d1f

+ 5 - 0
frameworks/Crystal/raze/README.md

@@ -0,0 +1,5 @@
+# Crystal-Raze
+
+This is the [Raze](https://github.com/samueleaton/raze) test of the Framework Benchmarks. Crystal is a new language that closely resembles Ruby with a goal of removing typed variables and parameters (instead inferencing), whilst maintaining top speed through bindings into C.
+
+Raze is a Modular, light web framework for Crystal https://razecr.com/

+ 28 - 0
frameworks/Crystal/raze/benchmark_config.json

@@ -0,0 +1,28 @@
+{
+  "framework": "raze",
+  "tests": [{
+    "default": {
+      "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": "Fullstack",
+      "database": "Postgres",
+      "framework": "raze",
+      "language": "Crystal",
+      "flavor": "None",
+      "orm": "micro",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Raze (PostgreSQL)",
+      "notes": "",
+      "versus": "crystal"
+    }
+  }]
+}

+ 107 - 0
frameworks/Crystal/raze/raze.cr

@@ -0,0 +1,107 @@
+require "raze"
+require "pg"
+
+BENCH_DB = DB.open("postgres://benchmarkdbuser:benchmarkdbpass@tfb-database:5432/hello_world")
+
+class CONTENT
+  ID_MAX = 10_000
+  JSON  = "application/json"
+  PLAIN = "text/plain"
+  HTML  = "text/html; charset=UTF-8"
+end
+
+private def get_world
+  id = Random.rand(CONTENT::ID_MAX).succ
+  random_number = BENCH_DB.query_one("SELECT randomNumber FROM world WHERE id = $1", id, as: Int32)
+  { id: id, randomNumber: random_number }
+end
+
+private def set_world(world)
+  BENCH_DB.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
+
+  BENCH_DB.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(ctx)
+  queries = ctx.query["queries"].as(String)
+  queries = queries.to_i? || 1
+  queries.clamp(1..500)
+end
+
+# Test 1: JSON Serialization
+get "/json" do |ctx|
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::JSON
+  { message: "Hello, World!" }.to_json
+end
+
+# Postgres Test 2: Single database query
+get "/db" do |ctx|
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::JSON
+  get_world.to_json
+end
+
+# Postgres Test 3: Multiple database query
+get "/queries" do |ctx|
+  results = (1..sanitized_query_count(ctx)).map do
+    get_world
+  end
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::JSON
+  results.to_json
+end
+
+# Postgres Test 4: Fortunes
+get "/fortunes" do |ctx|
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::HTML
+  data = fortunes
+  additional_fortune = {
+    id:      0,
+    message: "Additional fortune added at request time.",
+  }
+  data.push(additional_fortune)
+
+  data.sort_by! { |fortune| fortune[:message] }
+
+  render "views/fortunes.ecr"
+end
+
+# Postgres Test 5: Database Updates
+get "/updates" do |ctx|
+  updated = (1..sanitized_query_count(ctx)).map do
+    set_world({id: get_world[:id], randomNumber: Random.rand(CONTENT::ID_MAX).succ})
+  end
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::JSON
+  updated.to_json
+end
+
+# Test 6: Plaintext
+get "/plaintext" do |ctx|
+  ctx.response.headers["Server"] = "Raze"
+  ctx.response.headers["Date"] = Time.utc_now.to_s("%a, %d %b %Y %H:%M:%S GMT")
+  ctx.response.content_type = CONTENT::PLAIN
+  "Hello, World!"
+end
+
+Raze.config.logging = false
+Raze.config.port = 8080
+Raze.config.env = "production"
+Raze.config.reuse_port = true
+Raze.run

+ 13 - 0
frameworks/Crystal/raze/raze.dockerfile

@@ -0,0 +1,13 @@
+FROM crystallang/crystal:0.24.1
+
+WORKDIR /raze
+COPY views views
+COPY run.sh run.sh
+COPY raze.cr raze.cr
+COPY shard.lock shard.lock
+COPY shard.yml shard.yml
+
+RUN shards install
+RUN crystal build --release --no-debug raze.cr
+
+CMD bash run.sh

+ 7 - 0
frameworks/Crystal/raze/run.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+for i in $(seq 1 $(nproc --all)); do
+  ./raze -p 8080 &
+done
+
+wait

+ 22 - 0
frameworks/Crystal/raze/shard.lock

@@ -0,0 +1,22 @@
+version: 1.0
+shards:
+  db:
+    github: crystal-lang/crystal-db
+    version: 0.5.0
+
+  kilt:
+    github: jeromegn/kilt
+    version: 0.4.0
+
+  pg:
+    github: will/crystal-pg
+    version: 0.14.1
+
+  radix:
+    github: luislavena/radix
+    version: 0.3.8
+
+  raze:
+    github: samueleaton/raze
+    version: 0.2.1
+

+ 17 - 0
frameworks/Crystal/raze/shard.yml

@@ -0,0 +1,17 @@
+name: raze
+version: 0.1.0
+
+targets:
+  raze:
+    main: src/raze.cr
+
+crystal: 0.24.1
+
+license: MIT
+
+dependencies:
+  raze:
+    github: samueleaton/raze
+  pg:
+    github: will/crystal-pg
+    version: 0.14.1

+ 20 - 0
frameworks/Crystal/raze/views/fortunes.ecr

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Fortunes</title>
+</head>
+<body>
+	<table>
+		<tr>
+		<th>id</th>
+		<th>message</th>
+		</tr>
+		<% data.each do |fortune| %>
+			<tr>
+			<td><%= fortune[:id] %></td>
+			<td><%= HTML.escape(fortune[:message]) %></td>
+			</tr>
+		<% end %>
+	</table>
+</body>
+</html>