Explorar o código

Added concurrent queries & test for Crystal/kemal (#5376)

* Added concurrent query impl

* Create kemal-concurrent-queries.dockerfile

* Added concurrent-queries test

* Updated concurrency to 2

* Updated pool size
Steven Luu %!s(int64=5) %!d(string=hai) anos
pai
achega
07f2e5892e

+ 18 - 0
frameworks/Crystal/kemal/benchmark_config.json

@@ -23,6 +23,24 @@
       "display_name": "Kemal (PostgreSQL)",
       "notes": "",
       "versus": "crystal"
+    },
+    "concurrent-queries": {
+      "query_url": "/queries?concurrency=2&queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "kemal",
+      "language": "Crystal",
+      "flavor": "None",
+      "orm": "micro",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Kemal (PostgreSQL) - Concurrent Queries",
+      "notes": "",
+      "versus": "crystal"
     }
   }]
 }

+ 17 - 0
frameworks/Crystal/kemal/kemal-concurrent-queries.dockerfile

@@ -0,0 +1,17 @@
+FROM crystallang/crystal:0.32.1
+
+WORKDIR /kemal
+COPY views views
+COPY run.sh run.sh
+COPY server-postgres.cr server-postgres.cr
+COPY shard.lock shard.lock
+COPY shard.yml shard.yml
+
+ENV GC_MARKERS 1
+ENV KEMAL_ENV production
+ENV DATABASE_URL postgres://benchmarkdbuser:benchmarkdbpass@tfb-database:5432/hello_world?initial_pool_size=128&max_idle_pool_size=128
+
+RUN shards install
+RUN crystal build --release --no-debug server-postgres.cr
+
+CMD bash run.sh

+ 28 - 6
frameworks/Crystal/kemal/server-postgres.cr

@@ -1,5 +1,6 @@
 require "kemal"
 require "pg"
+require "commander"
 
 # Compose Objects (like Hash) to have a to_json method
 require "json/to_json"
@@ -17,7 +18,7 @@ ID_MAXIMUM = 10_000
 
 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, random_number = APPDB.query_one("SELECT id, randomNumber FROM world WHERE id = $1", id, as: {Int32, Int32})
   {id: id, randomNumber: random_number}
 end
 
@@ -37,14 +38,19 @@ private def fortunes
 end
 
 private def sanitized_query_count(request)
-  queries = request.params.query["queries"].as(String)
+  queries = request.params.query["queries"]? || "1"
   queries = queries.to_i? || 1
   queries.clamp(1..500)
 end
 
+private def sanitized_concurrency(request)
+  concurrency = request.params.query["concurrency"]? || "1"
+  concurrency.to_i? || 1
+end
+
 before_all do |env|
   env.response.headers["Server"] = "Kemal"
-  env.response.headers["Date"] = HTTP.format_time(Time.now)
+  env.response.headers["Date"] = HTTP.format_time(Time.utc)
 end
 
 #
@@ -75,9 +81,25 @@ end
 
 # Postgres Test 3: Multiple database query
 get "/queries" do |env|
-  results = (1..sanitized_query_count(env)).map do
-    random_world
-  end
+  queries = sanitized_query_count(env)
+  concurrency = sanitized_concurrency(env)
+
+  
+  results =
+    if concurrency < 2
+      (1..queries).map do
+        random_world
+      end
+    else
+      cmd = Commander(NamedTuple(id: Int32, randomNumber: Int32)).new(queries, concurrency)
+      queries.times do
+        cmd.dispatch do
+          random_world
+        end
+      end
+
+      cmd.collect
+    end
 
   env.response.content_type = CONTENT::JSON
   results.to_json

+ 4 - 0
frameworks/Crystal/kemal/shard.lock

@@ -1,5 +1,9 @@
 version: 1.0
 shards:
+  commander:
+    github: snluu/commander
+    commit: 9396efd427f06f0f6de5206f6e81d54fcd254abe
+
   db:
     github: crystal-lang/crystal-db
     version: 0.8.0

+ 2 - 0
frameworks/Crystal/kemal/shard.yml

@@ -13,3 +13,5 @@ dependencies:
   redis:
     github: stefanwille/crystal-redis
     version: 2.5.3
+  commander:
+    github: snluu/commander