Browse Source

Merge remote-tracking branch 'remotes/base/master' into vibed

Conflicts:
	.travis.yml
jin 10 years ago
parent
commit
03b0f6ccaf
59 changed files with 1091 additions and 387 deletions
  1. 2 0
      .travis.yml
  2. 24 0
      frameworks/Clojure/aleph/README.md
  3. 24 0
      frameworks/Clojure/aleph/benchmark_config.json
  4. 11 0
      frameworks/Clojure/aleph/hello/.gitignore
  5. 9 0
      frameworks/Clojure/aleph/hello/project.clj
  6. 44 0
      frameworks/Clojure/aleph/hello/src/hello/handler.clj
  7. 0 0
      frameworks/Clojure/aleph/hello/src/log4j.xml
  8. 3 0
      frameworks/Clojure/aleph/install.sh
  9. 10 0
      frameworks/Clojure/aleph/setup.sh
  10. 2 0
      frameworks/Clojure/aleph/source_code
  11. 10 29
      frameworks/Clojure/luminus/benchmark_config.json
  12. 3 4
      frameworks/Clojure/luminus/hello/.gitignore
  13. 1 0
      frameworks/Clojure/luminus/hello/Procfile
  14. 1 1
      frameworks/Clojure/luminus/hello/README.md
  15. 34 0
      frameworks/Clojure/luminus/hello/env/dev/clj/hello/repl.clj
  16. 48 39
      frameworks/Clojure/luminus/hello/project.clj
  17. 5 54
      frameworks/Clojure/luminus/hello/resources/public/css/screen.css
  18. 20 0
      frameworks/Clojure/luminus/hello/resources/sql/queries.sql
  19. 0 0
      frameworks/Clojure/luminus/hello/resources/templates/base.html
  20. 3 3
      frameworks/Clojure/luminus/hello/resources/templates/home.html
  21. 30 0
      frameworks/Clojure/luminus/hello/src/hello/core.clj
  22. 69 0
      frameworks/Clojure/luminus/hello/src/hello/db/core.clj
  23. 34 34
      frameworks/Clojure/luminus/hello/src/hello/handler.clj
  24. 37 0
      frameworks/Clojure/luminus/hello/src/hello/layout.clj
  25. 37 0
      frameworks/Clojure/luminus/hello/src/hello/middleware.clj
  26. 0 94
      frameworks/Clojure/luminus/hello/src/hello/models/db.clj
  27. 0 39
      frameworks/Clojure/luminus/hello/src/hello/models/schema.clj
  28. 24 50
      frameworks/Clojure/luminus/hello/src/hello/routes/home.clj
  29. 21 0
      frameworks/Clojure/luminus/hello/src/hello/session.clj
  30. 0 10
      frameworks/Clojure/luminus/hello/src/hello/views/layout.clj
  31. 2 4
      frameworks/Clojure/luminus/hello/test/hello/test/handler.clj
  32. 6 12
      frameworks/Clojure/luminus/setup.sh
  33. 23 14
      frameworks/Clojure/luminus/source_code
  34. 0 0
      frameworks/Python/historical/README.md
  35. 27 0
      frameworks/Python/historical/benchmark_config.json
  36. 18 0
      frameworks/Python/historical/install.sh
  37. 1 0
      frameworks/Python/historical/webware/.gitignore
  38. 6 0
      frameworks/Python/historical/webware/app/.cvsignore
  39. 27 0
      frameworks/Python/historical/webware/app/AppServer
  40. 27 0
      frameworks/Python/historical/webware/app/Configs/AppServer.config
  41. 6 0
      frameworks/Python/historical/webware/app/Configs/Application.config
  42. 2 0
      frameworks/Python/historical/webware/app/Context/.cvsignore
  43. 15 0
      frameworks/Python/historical/webware/app/Context/DbSession.py
  44. 23 0
      frameworks/Python/historical/webware/app/Context/Fortune.py
  45. 10 0
      frameworks/Python/historical/webware/app/Context/UrlHelper.py
  46. 13 0
      frameworks/Python/historical/webware/app/Context/World.py
  47. 16 0
      frameworks/Python/historical/webware/app/Context/db.py
  48. 23 0
      frameworks/Python/historical/webware/app/Context/fortune.py
  49. 11 0
      frameworks/Python/historical/webware/app/Context/json2.py
  50. 10 0
      frameworks/Python/historical/webware/app/Context/plaintext.py
  51. 20 0
      frameworks/Python/historical/webware/app/Context/queries.py
  52. 26 0
      frameworks/Python/historical/webware/app/Context/updates.py
  53. 33 0
      frameworks/Python/historical/webware/app/Launch.py
  54. 55 0
      frameworks/Python/historical/webware/app/WebKit.cgi
  55. 1 0
      frameworks/Python/historical/webware/app/adapter.address
  56. 1 0
      frameworks/Python/historical/webware/app/http.address
  57. 171 0
      frameworks/Python/historical/webware/app/webkit
  58. 3 0
      frameworks/Python/historical/webware/requirements.txt
  59. 9 0
      frameworks/Python/historical/webware/setup.sh

+ 2 - 0
.travis.yml

@@ -34,6 +34,7 @@ env:
     - "TESTDIR=Clojure/http-kit"
     - "TESTDIR=Clojure/http-kit"
     - "TESTDIR=Clojure/luminus"
     - "TESTDIR=Clojure/luminus"
     - "TESTDIR=Clojure/pedestal"
     - "TESTDIR=Clojure/pedestal"
+    - "TESTDIR=Clojure/aleph"
     - "TESTDIR=D/vibed"
     - "TESTDIR=D/vibed"
     - "TESTDIR=Dart/dart"
     - "TESTDIR=Dart/dart"
     - "TESTDIR=Dart/dart-redstone"
     - "TESTDIR=Dart/dart-redstone"
@@ -127,6 +128,7 @@ env:
     - "TESTDIR=Python/django"
     - "TESTDIR=Python/django"
     - "TESTDIR=Python/falcon"
     - "TESTDIR=Python/falcon"
     - "TESTDIR=Python/flask"
     - "TESTDIR=Python/flask"
+    - "TESTDIR=Python/historical"
     - "TESTDIR=Python/klein"
     - "TESTDIR=Python/klein"
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/tornado"
     - "TESTDIR=Python/tornado"

+ 24 - 0
frameworks/Clojure/aleph/README.md

@@ -0,0 +1,24 @@
+# Compojure Benchmarking Test
+
+This is the [Aleph](https;//github.com/ztellman/aleph) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test source](hello/src/hello/handler.clj)
+
+## Infrastructure Software Versions
+The dependencies are documented in [project.clj](hello/project.clj),
+but the main ones are:
+
+* [Aleph 0.4.0](https://github.com/ztellman/aleph)
+* [Clojure 1.7.0-beta2](http://clojure.org/)
+* [Cheshire 5.4.0](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
+
+## Test URLs
+### JSON Encoding Test
+
+http://localhost/json
+
+### Plaintext Test
+
+http://localhost/plaintext

+ 24 - 0
frameworks/Clojure/aleph/benchmark_config.json

@@ -0,0 +1,24 @@
+{
+  "framework": "aleph",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "aleph",
+      "language": "Clojure",
+      "orm": "Raw",
+      "platform": "Netty",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aleph",
+      "notes": "",
+      "versus": "netty"
+    }
+  }]
+}

+ 11 - 0
frameworks/Clojure/aleph/hello/.gitignore

@@ -0,0 +1,11 @@
+/target
+/lib
+/classes
+/checkouts
+pom.xml
+*.jar
+*.class
+.lein-deps-sum
+.lein-failures
+.lein-plugins
+.lein-env

+ 9 - 0
frameworks/Clojure/aleph/hello/project.clj

@@ -0,0 +1,9 @@
+(defproject hello "aleph"
+  :description "JSON/plaintext tests"
+  :dependencies [[org.clojure/clojure "1.7.0-beta2"]
+                 [clj-tuple "0.2.1"]
+                 [org.clojure/tools.cli "0.3.1"]
+                 [aleph "0.4.0"]
+                 [cheshire "5.4.0"]]
+  :main hello.handler
+  :aot :all)

+ 44 - 0
frameworks/Clojure/aleph/hello/src/hello/handler.clj

@@ -0,0 +1,44 @@
+(ns hello.handler
+  (:require
+    [byte-streams :as bs]
+    [clojure.tools.cli :as cli]
+    [aleph.http :as http]
+    [cheshire.core :as json]
+    [clj-tuple :as t])
+  (:gen-class))
+
+(def plaintext-response
+  (t/hash-map
+    :status 200
+    :headers (t/hash-map "content-type" "text/plain; charset=utf-8")
+    :body (bs/to-byte-array "Hello, World!")))
+
+(def json-response
+  (t/hash-map
+    :status 200
+    :headers (t/hash-map "content-type" "application/json")))
+
+(defn handler [{:keys [uri] :as req}]
+  (cond
+    (= "/plaintext" uri) plaintext-response
+    (= "/json" uri) (assoc json-response
+                      :body (json/encode (t/hash-map :message "Hello, World!")))
+    :else {:status 404}))
+
+;;;
+
+(defn -main [& args]
+
+  (let [[{:keys [help port]} _ banner]
+        (cli/cli args
+          ["-p" "--port" "Server port"
+           :default 8080
+           :parse-fn #(Integer/parseInt %)]
+          ["-h" "--[no-]help"])]
+
+    (when help
+      (println banner)
+      (System/exit 0))
+
+    (aleph.netty/leak-detector-level! :disabled)
+    (http/start-server handler {:port port, :executor :none})))

+ 0 - 0
frameworks/Clojure/luminus/hello/src/log4j.xml → frameworks/Clojure/aleph/hello/src/log4j.xml


+ 3 - 0
frameworks/Clojure/aleph/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends java7 leiningen

+ 10 - 0
frameworks/Clojure/aleph/setup.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+source $IROOT/java7.installed
+
+source $IROOT/lein.installed
+
+cd hello
+lein clean
+lein uberjar
+java -server -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=10 -jar target/*-standalone.jar &

+ 2 - 0
frameworks/Clojure/aleph/source_code

@@ -0,0 +1,2 @@
+./aleph/hello/src/hello/handler.clj
+./aleph/hello/project.clj

+ 10 - 29
frameworks/Clojure/luminus/benchmark_config.json

@@ -3,45 +3,26 @@
   "tests": [{
   "tests": [{
     "default": {
     "default": {
       "setup_file": "setup",
       "setup_file": "setup",
-      "json_url": "/luminus/json",
-      "db_url": "/luminus/db",
-      "query_url": "/luminus/db/",
-      "fortune_url": "/luminus/fortune",
-      "update_url": "/luminus/update/",
-      "plaintext_url": "/luminus/plaintext",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/queries/",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates/",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
-      "classification": "Micro",
-      "database": "MySQL",
-      "framework": "luminus",
-      "language": "Clojure",
-      "orm": "Full",
-      "platform": "Servlet",
-      "webserver": "Resin",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "luminus",
-      "notes": "",
-      "versus": "servlet"
-    },
-    "raw": {
-      "setup_file": "setup",
-      "db_url": "/luminus/dbraw",
-      "query_url": "/luminus/dbraw/",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
+      "classification": "Platform",
       "database": "MySQL",
       "database": "MySQL",
       "framework": "luminus",
       "framework": "luminus",
       "language": "Clojure",
       "language": "Clojure",
       "orm": "Raw",
       "orm": "Raw",
-      "platform": "Servlet",
-      "webserver": "Resin",
+      "platform": "http-kit",
+      "webserver": "None",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "luminus",
       "display_name": "luminus",
       "notes": "",
       "notes": "",
-      "versus": "servlet"
+      "versus": ""
     }
     }
   }]
   }]
 }
 }

+ 3 - 4
frameworks/Clojure/luminus/hello/.gitignore

@@ -5,7 +5,6 @@
 pom.xml
 pom.xml
 *.jar
 *.jar
 *.class
 *.class
-.lein-deps-sum
-.lein-failures
-.lein-plugins
-.lein-env
+/.lein-*
+/.env
+*.log

+ 1 - 0
frameworks/Clojure/luminus/hello/Procfile

@@ -0,0 +1 @@
+web: java $JVM_OPTS -cp target/hello.jar clojure.main -m hello.core

+ 1 - 1
frameworks/Clojure/luminus/hello/README.md

@@ -16,4 +16,4 @@ To start a web server for the application, run:
 
 
 ## License
 ## License
 
 
-Copyright © 2013 FIXME
+Copyright © 2015 FIXME

+ 34 - 0
frameworks/Clojure/luminus/hello/env/dev/clj/hello/repl.clj

@@ -0,0 +1,34 @@
+(ns hello.repl
+  (:use hello.handler
+    ring.server.standalone
+    [ring.middleware file-info file]))
+
+(defonce server (atom nil))
+
+(defn get-handler []
+  ;; #'app expands to (var app) so that when we reload our code,
+  ;; the server is forced to re-resolve the symbol in the var
+  ;; rather than having its own copy. When the root binding
+  ;; changes, the server picks it up without having to restart.
+  (-> #'app
+      ; Makes static assets in $PROJECT_DIR/resources/public/ available.
+      (wrap-file "resources")
+      ; Content-Type, Content-Length, and Last Modified headers for files in body
+      (wrap-file-info)))
+
+(defn start-server
+  "used for starting the server in development mode from REPL"
+  [& [port]]
+  (let [port (if port (Integer/parseInt port) 3000)]
+    (reset! server
+            (serve (get-handler)
+                   {:port port
+                    :init init
+                    :auto-reload? true
+                    :destroy destroy
+                    :join? false}))
+    (println (str "You can view the site at http://localhost:" port))))
+
+(defn stop-server []
+  (.stop @server)
+  (reset! server nil))

+ 48 - 39
frameworks/Clojure/luminus/hello/project.clj

@@ -1,40 +1,49 @@
-(defproject
-  hello
-  "luminus"
-  :dependencies
-  [[org.clojure/clojure "1.5.1"]
-   [lib-noir "0.8.2"]
-   [compojure "1.1.6"]
-   [ring-server "0.3.1"]
-   [selmer "0.5.7"]
-   [com.taoensso/timbre "2.7.1"]
-   [com.postspectacular/rotor "0.1.0"]
-   [com.taoensso/tower "2.0.2"]
-   [mysql/mysql-connector-java "5.1.28"]
-   [korma "0.3.0-RC6"]
-   [c3p0/c3p0 "0.9.1.2"]
-   [log4j
-    "1.2.17"
-    :exclusions
-    [javax.mail/mail
-     javax.jms/jms
-     com.sun.jdmk/jmxtools
-     com.sun.jmx/jmxri]]]
-  :ring
-  {:handler hello.handler/app,
-   :init hello.handler/init,
-   :destroy hello.handler/destroy}
+(defproject hello "luminus"
+
+  :description "Luminus framework benchmarks"
+  :url "https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Clojure/luminus"
+
+  :dependencies [[org.clojure/clojure "1.6.0"]
+                 [ring-server "0.4.0"]
+                 [selmer "0.8.2"]
+                 [com.taoensso/timbre "3.4.0"]
+                 [com.taoensso/tower "3.0.2"]
+                 [markdown-clj "0.9.65"]
+                 [environ "1.0.0"]
+                 [im.chit/cronj "1.4.3"]
+                 [compojure "1.3.3"]
+                 [ring/ring-defaults "0.1.4"]
+                 [ring/ring-session-timeout "0.1.0"]
+                 [ring-middleware-format "0.5.0"]
+                 [noir-exception "0.2.3"]
+                 [bouncer "0.3.2"]
+                 [prone "0.8.1"]
+                 [org.clojure/tools.nrepl "0.2.8"]
+                 [yesql "0.5.0-rc2"]
+                 [mysql/mysql-connector-java "5.1.6"]
+                 [c3p0/c3p0 "0.9.1.2"]
+                 [http-kit "2.1.19"]
+                 [org.clojure/tools.cli "0.2.1"]]
+
+  :min-lein-version "2.0.0"
+  :uberjar-name "hello.jar"
+  :jvm-opts ["-server"]
+
+  :main hello.core
+
+  :plugins [[lein-ring "0.9.1"]
+            [lein-environ "1.0.0"]]
+
   :profiles
   :profiles
-  {:uberjar {:aot :all}
-   :production
-   {:ring
-    {:open-browser? false, :stacktraces? false, :auto-reload? false}},
-   :dev
-   {:dependencies [[ring-mock "0.1.5"] [ring/ring-devel "1.2.2"]]}}
-  :url
-  "http://example.com/FIXME"
-  :plugins
-  [[lein-ring "0.8.10"]]
-  :description
-  "FIXME: write description"
-  :min-lein-version "2.0.0")
+  {:uberjar {:omit-source true
+             :env {:production true}
+             :aot :all}
+   :dev {:dependencies [[ring-mock "0.1.5"]
+                        [ring/ring-devel "1.3.2"]
+                        [pjstadig/humane-test-output "0.7.0"]]
+         :source-paths ["env/dev/clj"]
+
+         :repl-options {:init-ns hello.repl}
+         :injections [(require 'pjstadig.humane-test-output)
+                      (pjstadig.humane-test-output/activate!)]
+         :env {:dev true}}})

+ 5 - 54
frameworks/Clojure/luminus/hello/resources/public/css/screen.css

@@ -1,55 +1,6 @@
-body {	
-    background-color: #fff;
-    color: #333;
-    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+html,
+body {
+	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+    height: 100%;
+    padding-top: 40px;
 }
 }
-
-#register {
-    float: left;
-    display: inline-block;
-}
-
-h1 {
-    -webkit-border-radius: 4px;
-    -moz-border-radius: 4px;
-	background-color: #E9E9E9;
-	border: 1px solid #CFCFCF;
-	border-radius: 4px;
-}
-
-.nav li {
-    float: left;
-    list-style: none;
-    padding: 5px;
-}
-
-.navbar {
-    text-align: right;
-    padding: 5px;
-    margin-bottom: 10px;
-}
-
-#container {
-    height: auto;
-    margin-bottom: 10px;
-}
-
-#footer {    
-    width: 95%;
-    margin-left: 1%;
-    margin-right: 1%;
-    position:absolute;
-    bottom:0;
-    font-size: 11px;
-    font-weight: bold;
-    height: auto;    
-    text-align: center;
-    
-	padding-top: 10px;
-	
-	-webkit-border-radius: 4px;
-    -moz-border-radius: 4px;
-	background-color: #E9E9E9;
-	border: 1px solid #CFCFCF;
-	border-radius: 4px;
-}

+ 20 - 0
frameworks/Clojure/luminus/hello/resources/sql/queries.sql

@@ -0,0 +1,20 @@
+--name: get-world
+-- Query a World record from the database
+SELECT * FROM world
+WHERE id = :id
+
+--name: get-all-fortunes
+-- select all records from the fortune table
+SELECT * FROM fortune
+
+--name: update-world<!
+-- update an existing world record
+UPDATE world
+SET randomNumber = :randomNumber
+WHERE id = :id
+
+--name: get-all-fortunes
+-- query all fortune records
+SELECT id, message FROM fortune
+
+

+ 0 - 0
frameworks/Clojure/luminus/hello/src/hello/views/templates/base.html → frameworks/Clojure/luminus/hello/resources/templates/base.html


+ 3 - 3
frameworks/Clojure/luminus/hello/src/hello/views/templates/home.html → frameworks/Clojure/luminus/hello/resources/templates/home.html

@@ -1,4 +1,4 @@
-{% extends "hello/views/templates/base.html" %}
+{% extends "base.html" %}
 
 
 {% block content %}
 {% block content %}
 
 
@@ -13,6 +13,6 @@
     <td>{{message.message}}</td>
     <td>{{message.message}}</td>
   </tr>
   </tr>
   {% endfor %}
   {% endfor %}
-</table>  
-  
+</table>
+
 {% endblock %}
 {% endblock %}

+ 30 - 0
frameworks/Clojure/luminus/hello/src/hello/core.clj

@@ -0,0 +1,30 @@
+(ns hello.core
+  (:require [hello.handler :refer [app init]]
+            [clojure.tools.cli :refer [cli]]
+            [org.httpkit.server :refer [run-server]])
+  (:gen-class))
+
+(defn parse-port [s]
+  "Convert stringy port number int. Defaults to 8080."
+  (cond
+    (string? s) (Integer/parseInt s)
+    (instance? Integer s) s
+    (instance? Long s) (.intValue ^Long s)
+    :else 8080))
+
+(defn start-server [{:keys [port]}]
+  (let [cpu (.availableProcessors (Runtime/getRuntime))]
+    ;; double worker threads should increase database access performance
+    (init)
+    (run-server app {:port port :thread (* 2 cpu)})
+    (println (str "http-kit server listens at :" port))))
+
+(defn -main [& args]
+  (let [[options _ banner]
+        (cli args
+             ["-p" "--port" "Port to listen" :default 8080 :parse-fn parse-port]
+             ["--[no-]help" "Print this help"])]
+    (when (:help options)
+          (println banner)
+          (System/exit 0))
+    (start-server options)))

+ 69 - 0
frameworks/Clojure/luminus/hello/src/hello/db/core.clj

@@ -0,0 +1,69 @@
+(ns hello.db.core
+  (:require
+    [yesql.core :refer [defqueries]])
+  (:import com.mchange.v2.c3p0.ComboPooledDataSource))
+
+(def db-spec
+  {:classname "com.mysql.jdbc.Driver"
+   :subprotocol "mysql"
+   :subname "//localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
+   :user "benchmarkdbuser"
+   :password "benchmarkdbpass"})
+
+(defn pool
+  [spec]
+  {:datasource
+   (doto (ComboPooledDataSource.)
+     (.setDriverClass (:classname spec))
+     (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
+     (.setUser (:user spec))
+     (.setPassword (:password spec))
+     ;; expire excess connections after 30 minutes of inactivity:
+     (.setMaxIdleTimeExcessConnections (* 30 60))
+     ;; expire connections after 3 hours of inactivity:
+     (.setMaxIdleTime (* 3 60 60)))})
+
+(defonce db (atom nil))
+
+(defn connect! []
+  (reset! db (pool db-spec)))
+
+(defqueries "sql/queries.sql")
+
+(defn get-world-random
+  "Query a random World record between 1 and 10,000 from the database"
+  []
+  (get-world {:id (inc (rand-int 9999))} {:connection @db}))
+
+(defn get-query-count [queries]
+  "Parse provided string value of query count, clamping values to between 1 and 500."
+  (let [n (try (Integer/parseInt queries)
+               (catch Exception e 1))] ; default to 1 on parse failure
+    (cond
+      (< n 1) 1
+      (> n 500) 500
+      :else n)))
+
+(defn run-queries
+  "Run the specified number of queries, return the results"
+  [queries]
+  (flatten (repeatedly (get-query-count queries) get-world-random)))
+
+(defn get-fortunes []
+   "Fetch the full list of Fortunes from the database, sort them by the fortune
+  message text, and then return the results."
+  (sort-by
+   :message
+   (conj (get-all-fortunes {} {:connection @db})
+         {:id 0 :message "Additional fortune added at request time."})))
+
+(defn update-and-persist
+  "Changes the :randomNumber of a number of world entities.
+  Persists the changes to sql then returns the updated entities"
+  [queries]
+  (for [world (-> queries run-queries)]
+    (let [updated-world (assoc world :randomNumber (inc (rand-int 9999)))]
+      (update-world<! updated-world {:connection @db})
+      updated-world)))
+
+

+ 34 - 34
frameworks/Clojure/luminus/hello/src/hello/handler.clj

@@ -1,20 +1,20 @@
 (ns hello.handler
 (ns hello.handler
-  (:use hello.routes.home
-        compojure.core)
-  (:require [noir.util.middleware :as middleware]
+  (:require [compojure.core :refer [defroutes routes]]
+            [hello.routes.home :refer [home-routes]]
+            [hello.db.core :as db]
+            [hello.middleware
+             :refer [development-middleware production-middleware]]
+            [hello.session :as session]
             [compojure.route :as route]
             [compojure.route :as route]
             [taoensso.timbre :as timbre]
             [taoensso.timbre :as timbre]
-            [taoensso.timbre.appenders.rotor :as rotor]))
-
-
-(defroutes app-routes
-  (route/resources "/")
-  (route/not-found "Not Found"))
-
-
-(defn destroy []
-  (timbre/info "picture-gallery is shutting down"))
+            [taoensso.timbre.appenders.rotor :as rotor]
+            [selmer.parser :as parser]
+            [environ.core :refer [env]]
+            [cronj.core :as cronj]))
 
 
+(defroutes base-routes
+           (route/resources "/")
+           (route/not-found "Not Found"))
 
 
 (defn init
 (defn init
   "init will be called once when
   "init will be called once when
@@ -24,34 +24,34 @@
   []
   []
   (timbre/set-config!
   (timbre/set-config!
     [:appenders :rotor]
     [:appenders :rotor]
-    {:min-level :info
-     :enabled? true
-     :async? false ; should be always false for rotor
+    {:min-level             :info
+     :enabled?              true
+     :async?                false ; should be always false for rotor
      :max-message-per-msecs nil
      :max-message-per-msecs nil
-     :fn rotor/appender-fn})
+     :fn                    rotor/appender-fn})
 
 
   (timbre/set-config!
   (timbre/set-config!
     [:shared-appender-config :rotor]
     [:shared-appender-config :rotor]
-    {:path "{{sanitized}}.log" :max-size (* 512 1024) :backlog 10})
-
-  (timbre/info "hello started successfully"))
+    {:path "hello.log" :max-size (* 512 1024) :backlog 10})
 
 
+  (if (env :dev) (parser/cache-off!))
+  (db/connect!)
+  ;;start the expired session cleanup job
+  (cronj/start! session/cleanup-job)
+  (timbre/info "\n-=[ hello started successfully"
+               (when (env :dev) "using the development profile") "]=-"))
 
 
 (defn destroy
 (defn destroy
   "destroy will be called when your application
   "destroy will be called when your application
    shuts down, put any clean up code here"
    shuts down, put any clean up code here"
   []
   []
-  (timbre/info "hello is shutting down..."))
-
-
-(def app (middleware/app-handler
-           ;; add your application routes here
-           [home-routes app-routes]
-           ;; add custom middleware here
-           :middleware []
-           ;; add access rules here
-           :access-rules []
-           ;; serialize/deserialize the following data formats
-           ;; available formats:
-           ;; :json :json-kw :yaml :yaml-kw :edn :yaml-in-html
-           :formats [:json-kw :edn]))
+  (timbre/info "hello is shutting down...")
+  (cronj/shutdown! session/cleanup-job)
+  (timbre/info "shutdown complete!"))
+
+(def app
+  (-> (routes
+        home-routes
+        base-routes)
+      development-middleware
+      production-middleware))

+ 37 - 0
frameworks/Clojure/luminus/hello/src/hello/layout.clj

@@ -0,0 +1,37 @@
+(ns hello.layout
+  (:require [selmer.parser :as parser]
+            [selmer.filters :as filters]
+            [markdown.core :refer [md-to-html-string]]
+            [ring.util.response :refer [content-type response]]
+            [compojure.response :refer [Renderable]]
+            [ring.util.anti-forgery :refer [anti-forgery-field]]
+            [ring.middleware.anti-forgery :refer [*anti-forgery-token*]]
+            [environ.core :refer [env]]))
+
+(parser/set-resource-path!  (clojure.java.io/resource "templates"))
+
+(parser/add-tag! :csrf-field (fn [_ _] (anti-forgery-field)))
+(filters/add-filter! :markdown (fn [content] [:safe (md-to-html-string content)]))
+
+(deftype RenderableTemplate [template params]
+  Renderable
+  (render [this request]
+    (content-type
+      (->> (assoc params
+                  :page template
+                  :dev (env :dev)
+                  :csrf-token *anti-forgery-token*
+                  :servlet-context
+                  (if-let [context (:servlet-context request)]
+                    ;; If we're not inside a serlvet environment (for
+                    ;; example when using mock requests), then
+                    ;; .getContextPath might not exist
+                    (try (.getContextPath context)
+                         (catch IllegalArgumentException _ context))))
+        (parser/render-file (str template))
+        response)
+      "text/html; charset=utf-8")))
+
+(defn render [template & [params]]
+  (RenderableTemplate. template params))
+

+ 37 - 0
frameworks/Clojure/luminus/hello/src/hello/middleware.clj

@@ -0,0 +1,37 @@
+(ns hello.middleware
+  (:require [hello.session :as session]
+            [taoensso.timbre :as timbre]
+            [environ.core :refer [env]]
+            [selmer.middleware :refer [wrap-error-page]]
+            [prone.middleware :refer [wrap-exceptions]]
+            [ring.util.response :refer [redirect]]
+            [ring.middleware.defaults :refer [site-defaults wrap-defaults]]
+            [ring.middleware.session-timeout :refer [wrap-idle-session-timeout]]
+            [noir-exception.core :refer [wrap-internal-error]]
+            [ring.middleware.session.memory :refer [memory-store]]
+            [ring.middleware.format :refer [wrap-restful-format]]
+            
+            ))
+
+(defn log-request [handler]
+  (fn [req]
+    (timbre/debug req)
+    (handler req)))
+
+(defn development-middleware [handler]
+  (if (env :dev)
+    (-> handler
+        wrap-error-page
+        wrap-exceptions)
+    handler))
+
+(defn production-middleware [handler]
+  (-> handler
+      
+      (wrap-restful-format :formats [:json-kw :edn :transit-json :transit-msgpack])
+      (wrap-idle-session-timeout
+        {:timeout (* 60 30)
+         :timeout-response (redirect "/")})
+      (wrap-defaults
+        (assoc-in site-defaults [:session :store] (memory-store session/mem)))
+      (wrap-internal-error :log #(timbre/error %))))

+ 0 - 94
frameworks/Clojure/luminus/hello/src/hello/models/db.clj

@@ -1,94 +0,0 @@
-(ns hello.models.db
-  (:use korma.core
-         hello.models.schema)
-  (:require [clojure.java.jdbc :as jdbc]))
-
-
-
-; Set up entity World and the database representation
-(defentity world
-  (pk :id)
-  (table :world)
-  (entity-fields :id :randomNumber)
-  (database db))
-
-
-(defn get-world
-  "Query a random World record from the database"
-  []
-  (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
-    (select world
-            (fields :id :randomNumber)
-            (where {:id id }))))
-
-
-(defn get-world-raw
-  "Query a random World record from the database"
-  []
-  (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
-    (jdbc/with-connection (db-raw)
-      ; Set a naming strategy to preserve column name case
-      (jdbc/with-naming-strategy {:keyword identity}
-        (jdbc/with-query-results rs [(str "select * from world where id = ?") id]
-          (doall rs))))))
-
-
-(defn run-queries
-  "Run the specified number of queries, return the results"
-  [queries]
-  (flatten ; Make it a list of maps
-    (take queries
-          (repeatedly get-world))))
-
-
-(defn run-queries-raw [queries]
-  "Run the specified number of queries, return the results"
-  (flatten ; Make it a list of maps
-    (take queries
-          (repeatedly get-world-raw))))
-
-
-(defn get-query-count [queries]
-  "Parse provided string value of query count, clamping values to between 1 and 500."
-  (let [q (try (Integer/parseInt queries)
-               (catch Exception e 1))] ; default to 1 on parse failure
-    (if (> q 500)
-      500 ; clamp to 500 max
-      (if (< q 1)
-        1 ; clamp to 1 min
-        q)))) ; otherwise use provided value
-
-
-; Set up entity World and the database representation
-(defentity fortune
-  (pk :id)
-  (table :fortune)
-  (entity-fields :id :message)
-  (database db))
-
-
-(def get-all-fortunes
-  "Query all Fortune records from the database."
-  (select fortune
-          (fields :id :message)))
-
-
-(def get-fortunes
-  "Fetch the full list of Fortunes from the database. Insert an additional fortune at runtime.
-  Then sort all by fortune message text. Return the results."
-  (let [fortunes (conj get-all-fortunes
-                       {:id 0 :message "Additional fortune added at request time."})]
-    (sort-by :message fortunes)))
-
-
-(defn update-and-persist
-  "Changes the :randomNumber of a number of world entities.
-  Persists the changes to sql then returns the updated entities"
-  [queries]
-  (let [results (run-queries queries)]
-    (for [w results]
-      (update-in w [:randomNumber (inc (rand-int 9999))]
-        (update world
-                (set-fields {:randomNumber (:randomNumber w)})
-                (where {:id [:id w]}))))
-    results))

+ 0 - 39
frameworks/Clojure/luminus/hello/src/hello/models/schema.clj

@@ -1,39 +0,0 @@
-(ns hello.models.schema
-  (:require [korma.db :refer [defdb mysql]]
-            [clojure.java.jdbc :as sql])
-  (:import com.mchange.v2.c3p0.ComboPooledDataSource))
-
-; Database connection for java.jdbc "raw"
-; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
-(def db-spec-mysql-raw
-  {:classname "com.mysql.jdbc.Driver"
-   :subprotocol "mysql"
-   :subname "//localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
-   :user "benchmarkdbuser"
-   :password "benchmarkdbpass"})
-
-; Database connection
-(defdb db (mysql {:subname "//localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
-                  :user "benchmarkdbuser"
-                  :password "benchmarkdbpass"
-                  ;;OPTIONAL KEYS
-                  :delimiters "" ;; remove delimiters
-                  :maximum-pool-size 256
-                  }))
-                  
-(defn pool
-  [spec]
-  (let [cpds (doto (ComboPooledDataSource.)
-               (.setDriverClass (:classname spec))
-               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
-               (.setUser (:user spec))
-               (.setPassword (:password spec))
-               ;; expire excess connections after 30 minutes of inactivity:
-               (.setMaxIdleTimeExcessConnections (* 30 60))
-               ;; expire connections after 3 hours of inactivity:
-               (.setMaxIdleTime (* 3 60 60)))]
-    {:datasource cpds}))
-
-(def pooled-db (delay (pool db-spec-mysql-raw)))
-
-(defn db-raw [] @pooled-db)

+ 24 - 50
frameworks/Clojure/luminus/hello/src/hello/routes/home.clj

@@ -1,75 +1,49 @@
 (ns hello.routes.home
 (ns hello.routes.home
-  (:use compojure.core
-        hello.models.db)
-  (:require [hello.views.layout :as layout]
-            [noir.response :as response]))
-
+  (:require [hello.layout :as layout]
+            [hello.db.core :as db]
+            [compojure.core :refer [defroutes GET]]
+            [ring.util.response :refer [response]]
+            [clojure.java.io :as io]))
 
 
 (def json-serialization
 (def json-serialization
   "Test 1: JSON serialization"
   "Test 1: JSON serialization"
-  (response/json {:message "Hello, World!"}))
-
+  (response {:message "Hello, World!"}))
 
 
-(def single-query-test
+(defn single-query-test
   "Test 2: Single database query"
   "Test 2: Single database query"
-  (response/json (first (run-queries 1))))
-
+  []
+  (-> 1 db/run-queries first response))
 
 
 (defn multiple-query-test
 (defn multiple-query-test
   "Test 3: Multiple database query"
   "Test 3: Multiple database query"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (get-query-count)
-      (run-queries)
-      (response/json)))
-
+      db/run-queries
+      response))
 
 
-(def single-query-test-raw
-  "Test 2: Single database query (raw)"
-  (-> 1
-      (run-queries-raw)
-      (first)
-      (response/json)))
-
-
-(defn multiple-query-test-raw
-  "Test 3: Multiple database query (raw)"
-  [queries]
-  (-> queries
-      (get-query-count)
-      (run-queries-raw)
-      (response/json)))
-
-
-(def fortunes
+(defn fortunes
   "Test 4: Fortunes"
   "Test 4: Fortunes"
-  (layout/render "home.html"
-                 {:messages get-fortunes}))
-
+  []
+  (layout/render "home.html" {:messages (db/get-fortunes)}))
 
 
 (defn db-update
 (defn db-update
   "Test 5: Database updates"
   "Test 5: Database updates"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (get-query-count)
-      (update-and-persist)
-      (response/json)))
-
+      db/update-and-persist
+      response))
 
 
 (def plaintext
 (def plaintext
   "Test 6: Plaintext"
   "Test 6: Plaintext"
   {:status 200
   {:status 200
-   :headers {"Content-Type" "text/plain; charset=utf-8"}
+   :headers {"Content-Type" "text/plain"}
    :body "Hello, World!"})
    :body "Hello, World!"})
 
 
-
 (defroutes home-routes
 (defroutes home-routes
-  (GET "/"                [] "Hello, World!")
-  (GET "/plaintext"       [] plaintext)
-  (GET "/json"            [] json-serialization)
-  (GET "/db"              [] single-query-test)
-  (GET "/db/:queries"     [queries] (multiple-query-test queries))
-  (GET "/dbraw"           [] single-query-test-raw)
-  (GET "/dbraw/:queries"  [queries] (multiple-query-test-raw queries))
-  (GET "/fortune"         [] fortunes)
-  (GET "/update/:queries" [queries] (db-update queries)))
+  (GET "/"                 [] "Hello, World!")
+  (GET "/plaintext"        [] plaintext)
+  (GET "/json"             [] json-serialization)
+  (GET "/db"               [] (single-query-test))
+  (GET "/queries/:queries" [queries] (multiple-query-test queries))
+  (GET "/fortunes"         [] (fortunes))
+  (GET "/updates/:queries"  [queries] (db-update queries)))

+ 21 - 0
frameworks/Clojure/luminus/hello/src/hello/session.clj

@@ -0,0 +1,21 @@
+(ns hello.session
+  (:require [cronj.core :refer [cronj]]))
+
+(defonce mem (atom {}))
+
+(defn- current-time []
+  (quot (System/currentTimeMillis) 1000))
+
+(defn- expired? [[id session]]
+  (pos? (- (:ring.middleware.session-timeout/idle-timeout session) (current-time))))
+
+(defn clear-expired-sessions []
+  (clojure.core/swap! mem #(->> % (filter expired?) (into {}))))
+
+(def cleanup-job
+  (cronj
+    :entries
+    [{:id "session-cleanup"
+      :handler (fn [_ _] (clear-expired-sessions))
+      :schedule "* /30 * * * * *"
+      :opts {}}]))

+ 0 - 10
frameworks/Clojure/luminus/hello/src/hello/views/layout.clj

@@ -1,10 +0,0 @@
-(ns hello.views.layout
-  (:use noir.request)
-  (:require [selmer.parser :as parser]))
-
-(def template-path "hello/views/templates/")
-
-(defn render [template & [params]]
-  (parser/render-file (str template-path template)
-                      (assoc params :context (:context *request*))))
-

+ 2 - 4
frameworks/Clojure/luminus/hello/test/hello/test/handler.clj

@@ -6,10 +6,8 @@
 (deftest test-app
 (deftest test-app
   (testing "main route"
   (testing "main route"
     (let [response (app (request :get "/"))]
     (let [response (app (request :get "/"))]
-      (is (= (:status response) 200))
-      (is (= (:body response)
-             "Hello, World!"))))
+      (is (= 200 (:status response)))))
 
 
   (testing "not-found route"
   (testing "not-found route"
     (let [response (app (request :get "/invalid"))]
     (let [response (app (request :get "/invalid"))]
-      (is (= (:status response) 404)))))
+      (is (= 404 (:status response))))))

+ 6 - 12
frameworks/Clojure/luminus/setup.sh

@@ -1,19 +1,13 @@
 #!/bin/bash
 #!/bin/bash
-
 source $IROOT/java7.installed
 source $IROOT/java7.installed
-
 source $IROOT/lein.installed
 source $IROOT/lein.installed
 
 
-export RESIN_HOME=${IROOT}/resin-4.0.41
-
-# Path vars must be set here
-export PATH="$JAVA_HOME/bin:$PATH"
-
-sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/models/schema.clj
+# Update db host in the source file
+sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/db/core.clj
 
 
 cd hello
 cd hello
 lein clean
 lein clean
-lein ring uberwar
-rm -rf $RESIN_HOME/webapps/*
-cp target/hello-luminus-standalone.war $RESIN_HOME/webapps/luminus.war
-$RESIN_HOME/bin/resinctl start
+rm -rf target
+# pack all dependencies into a single jar: target/http-kit-standalone.jar
+lein uberjar
+java -server -jar target/hello.jar  &

+ 23 - 14
frameworks/Clojure/luminus/source_code

@@ -1,23 +1,32 @@
+./luminus/hello/Procfile
+./luminus/hello/README.md
 ./luminus/hello/project.clj
 ./luminus/hello/project.clj
-./luminus/hello/src/
-./luminus/hello/src/log4j.xml
-./luminus/hello/src/hello
-./luminus/hello/src/hello/routes
-./luminus/hello/src/hello/routes/home.clj
-./luminus/hello/src/hello/views
-./luminus/hello/src/hello/views/templates
-./luminus/hello/src/hello/views/templates/base.html
-./luminus/hello/src/hello/views/templates/home.html
-./luminus/hello/src/hello/views/layout.clj
-./luminus/hello/src/hello/handler.clj
-./luminus/hello/src/hello/models
-./luminus/hello/src/hello/models/schema.clj
-./luminus/hello/src/hello/models/db.clj
+./luminus/hello/env/
+./luminus/hello/env/dev/clj
+./luminus/hello/env/dev/clj/hello
+./luminus/hello/env/dev/clj/hello/repl.clj
 ./luminus/hello/resources/
 ./luminus/hello/resources/
 ./luminus/hello/resources/public
 ./luminus/hello/resources/public
 ./luminus/hello/resources/public/css
 ./luminus/hello/resources/public/css
 ./luminus/hello/resources/public/css/screen.css
 ./luminus/hello/resources/public/css/screen.css
+./luminus/hello/resources/sql
+./luminus/hello/resources/sql/queries.sql
+./luminus/hello//resources/templates
+./luminus/hello//resources/templates/base.html
+./luminus/hello//resources/templates/home.html
+./luminus/hello/src/
+./luminus/hello/src/hello
+./luminus/hello/src/hello/core.clj
+./luminus/hello/src/hello/handler.clj
+./luminus/hello/src/hello/layout.clj
+./luminus/hello/src/hello/middleware.clj
+./luminus/hello/src/hello/session.clj
+./luminus/hello/src/hello/db
+./luminus/hello/src/hello/db/core.clj
+./luminus/hello/src/hello/routes
+./luminus/hello/src/hello/routes/home.clj
 ./luminus/hello/test/
 ./luminus/hello/test/
 ./luminus/hello/test/hello
 ./luminus/hello/test/hello
 ./luminus/hello/test/hello/test
 ./luminus/hello/test/hello/test
 ./luminus/hello/test/hello/test/handler.clj
 ./luminus/hello/test/hello/test/handler.clj
+

+ 0 - 0
frameworks/Python/historical/README.md


+ 27 - 0
frameworks/Python/historical/benchmark_config.json

@@ -0,0 +1,27 @@
+{
+  "framework": "historical",
+  "tests": [{
+    "webware": {
+      "setup_file": "webware/setup",
+      "json_url": "/json2",
+      "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "update_url": "/updates?queries=",
+      "fortune_url": "/fortune",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "MySQL",
+      "framework": "Webware",
+      "language": "Python",
+      "orm": "Full",
+      "platform": "Apache",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Webware",
+      "notes": "CPython 2.7"
+    }
+  }]
+}

+ 18 - 0
frameworks/Python/historical/install.sh

@@ -0,0 +1,18 @@
+
+export PY2_ROOT=$IROOT/py2
+export PY2=$PY2_ROOT/bin/python
+export PY2_PIP=$PY2_ROOT/bin/pip
+
+mkdir -p $IROOT/.pip_cache
+export PIP_DOWNLOAD_CACHE=$IROOT/.pip_cache
+
+fw_depends python2 apache
+
+$PY2_PIP install --install-option="--prefix=${PY2_ROOT}" -r $TROOT/webware/requirements.txt
+
+cd $TROOT/webware 
+rm -fr Webware Webware-1.1.1
+rm Webware-1.1.1.tar.gz
+wget downloads.sourceforge.net/webware/Webware-1.1.1.tar.gz
+tar -xf Webware-1.1.1.tar.gz
+cp -r app/ Webware-1.1.1/

+ 1 - 0
frameworks/Python/historical/webware/.gitignore

@@ -0,0 +1 @@
+Webware*

+ 6 - 0
frameworks/Python/historical/webware/app/.cvsignore

@@ -0,0 +1,6 @@
+*.pyc
+*.pyo
+address.*
+httpd.*
+appserverpid.*
+profile.pstats

+ 27 - 0
frameworks/Python/historical/webware/app/AppServer

@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# WebKit application server launch script for Unix.
+# This wrapper script is needed for the AutoReload mechanism.
+
+# You may want to use a specific Python executable:
+PYTHON=python
+
+# You may give the following Python parameters in advance,
+# followed by the parameters passed on to ThreadedAppServer:
+#   -O with optimization (.pyo instead of .pyc)
+#   -u unbuffered output (useful for debugging)
+unset PY_OPTS
+while [ "$1" = "-O" -o "$1" = "-u" ]; do
+    PY_OPTS="$PY_OPTS $1"
+    shift
+done
+
+# Make the directory where this script lives the current directory:
+cd `dirname $0`
+
+# As long as the app server returns a 3, it wants to be restarted:
+errorlevel=3
+while [ $errorlevel -eq 3 ]; do
+    $PYTHON$PY_OPTS Launch.py ThreadedAppServer $*
+    errorlevel=$?
+done

+ 27 - 0
frameworks/Python/historical/webware/app/Configs/AppServer.config

@@ -0,0 +1,27 @@
+# AppServer.config file for Webware for Python
+
+PrintConfigAtStartUp = False
+Verbose = False # verbose output
+
+PlugInDirs = [WebwarePath] # load all Webware plug-ins
+PlugIns = [] # use this if you want to load specific plug-ins only
+
+# This is the IP address at which the application server will listen:
+Host = 'localhost' # use '' for listening on all network interfaces
+
+EnableAdapter = True # enable WebKit adapter
+AdapterPort = 8086
+
+EnableHTTP = True # enable built-in Webserver
+HTTPPort = 8080
+
+# The initial, minimum and maxium number of worker threads:
+StartServerThreads = 10
+MinServerThreads = 5
+MaxServerThreads = 20
+
+# The maximum execution time for AppServer requests:
+MaxRequestTime = 300 # specified in seconds
+
+# You can activate auto reloading on source changes here:
+AutoReload = True

+ 6 - 0
frameworks/Python/historical/webware/app/Configs/Application.config

@@ -0,0 +1,6 @@
+Contexts = {}
+Contexts['default'] = 'Context'
+
+PrintConfigAtStartUp = False
+LogActivity = False
+Verbose = False

+ 2 - 0
frameworks/Python/historical/webware/app/Context/.cvsignore

@@ -0,0 +1,2 @@
+*.pyc
+*.pyo

+ 15 - 0
frameworks/Python/historical/webware/app/Context/DbSession.py

@@ -0,0 +1,15 @@
+import os
+
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+
+DBDRIVER = 'mysql'
+DBHOSTNAME = os.environ.get('DBHOST', 'localhost')
+DATABASE_URI = '%s://benchmarkdbuser:benchmarkdbpass@%s:3306/hello_world?charset=utf8' % (DBDRIVER, DBHOSTNAME)
+
+class Database():
+	Base = declarative_base()
+	db_engine = create_engine(DATABASE_URI)
+	Session = sessionmaker(bind=db_engine)
+	DbSession = Session()

+ 23 - 0
frameworks/Python/historical/webware/app/Context/Fortune.py

@@ -0,0 +1,23 @@
+import json
+import bleach
+from random import randint
+from operator import attrgetter
+
+from WebKit.Page import Page
+from DbSession import Database
+from Fortune import Fortune
+
+class fortune(Page):
+	def writeHTML(self):
+		output = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>"
+		self.response().clearHeaders()
+		self.response()._headers["Content-Type"] = "text/html; charset=UTF-8"
+		fortunes = Database.DbSession.query(Fortune).all()
+		fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
+		fortunes.sort(key=attrgetter("message"))
+		for fortune in fortunes:
+			message = bleach.clean(fortune.message)
+			output += "<tr><td>%s</td><td>%s</td></tr>" % (fortune.id , message.encode("utf-8"))
+		output += "</table></body></html>"
+		self.response()._headers["Content-Length"] = len(output)
+		self.writeln(output)

+ 10 - 0
frameworks/Python/historical/webware/app/Context/UrlHelper.py

@@ -0,0 +1,10 @@
+def getQueryNum(queryString):
+    try:
+        num_queries = int(queryString)
+        if num_queries < 1:
+            return 1
+        if num_queries > 500:
+            return 500
+        return num_queries
+    except ValueError:
+        return 1

+ 13 - 0
frameworks/Python/historical/webware/app/Context/World.py

@@ -0,0 +1,13 @@
+from DbSession import Database
+from sqlalchemy import Column
+from sqlalchemy.types import Integer
+
+class World(Database.Base):
+    __tablename__ = "World"
+    id = Column(Integer, primary_key=True)
+    randomNumber = Column(Integer)
+    def serialize(self):
+        return {
+            'id': self.id,
+            'randomNumber': self.randomNumber,
+        }

+ 16 - 0
frameworks/Python/historical/webware/app/Context/db.py

@@ -0,0 +1,16 @@
+
+from WebKit.HTTPContent import HTTPContent
+from DbSession import Database
+from World import World
+import json
+from random import randint
+
+class db(HTTPContent):
+    def defaultAction(self):
+        self.response().clearHeaders()
+        self.response()._headers["Content-Type"] = "application/json"
+        wid = randint(1, 10000)
+        world = Database.DbSession.query(World).get(wid).serialize()
+        output = json.dumps(world)
+        self.response()._headers["Content-Length"] = len(output)
+        self.write(output)

+ 23 - 0
frameworks/Python/historical/webware/app/Context/fortune.py

@@ -0,0 +1,23 @@
+import json
+import bleach
+from random import randint
+from operator import attrgetter
+
+from WebKit.Page import Page
+from DbSession import Database
+from Fortune import Fortune
+
+class fortune(Page):
+	def writeHTML(self):
+		output = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>"
+		self.response().clearHeaders()
+		self.response()._headers["Content-Type"] = "text/html; charset=UTF-8"
+		fortunes = Database.DbSession.query(Fortune).all()
+		fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
+		fortunes.sort(key=attrgetter("message"))
+		for fortune in fortunes:
+			message = bleach.clean(fortune.message)
+			output += "<tr><td>%s</td><td>%s</td></tr>" % (fortune.id , message.encode("utf-8"))
+		output += "</table></body></html>"
+		self.response()._headers["Content-Length"] = len(output)
+		self.writeln(output)

+ 11 - 0
frameworks/Python/historical/webware/app/Context/json2.py

@@ -0,0 +1,11 @@
+
+from WebKit.HTTPContent import HTTPContent
+import json
+
+class json2(HTTPContent):
+    def defaultAction(self):
+        self.response().clearHeaders()
+        self.response()._headers["Content-Type"] = "application/json"
+        output = json.dumps({"message": "Hello, World!"})		
+        self.response()._headers["Content-Length"] = len(output)		
+        self.write(output)

+ 10 - 0
frameworks/Python/historical/webware/app/Context/plaintext.py

@@ -0,0 +1,10 @@
+
+from WebKit.HTTPContent import HTTPContent
+
+class plaintext(HTTPContent):
+    def defaultAction(self):
+    	self.response().clearHeaders()
+        self.response()._headers["Content-Type"] = "text/plain"
+        output = "Hello, World!"
+        self.response()._headers["Content-Length"] = len(output)
+        self.write(output)

+ 20 - 0
frameworks/Python/historical/webware/app/Context/queries.py

@@ -0,0 +1,20 @@
+import json
+from random import randint
+from functools import partial
+
+from WebKit.HTTPContent import HTTPContent
+from DbSession import Database
+from World import World
+import UrlHelper 
+
+class queries(HTTPContent):
+    def defaultAction(self):
+        self.response().clearHeaders()
+        self.response()._headers["Content-Type"] = "application/json"
+        num_queries = UrlHelper.getQueryNum(self.request().field("queries"))
+        rp = partial(randint, 1, 10000)
+        get = Database.DbSession.query(World).get
+        worlds = [get(rp()).serialize() for _ in xrange(num_queries)]
+        output = json.dumps(worlds)
+        self.response()._headers["Content-Length"] = len(output)
+        self.write(output)

+ 26 - 0
frameworks/Python/historical/webware/app/Context/updates.py

@@ -0,0 +1,26 @@
+import json
+from random import randint
+from functools import partial
+
+from WebKit.HTTPContent import HTTPContent
+from DbSession import Database
+from World import World
+import UrlHelper 
+
+class updates(HTTPContent):
+    def defaultAction(self):
+        self.response().clearHeaders()
+        self.response()._headers["Content-Type"] = "application/json"
+        num_queries = UrlHelper.getQueryNum(self.request().field("queries"))
+        worlds = []
+        rp = partial(randint, 1, 10000)
+        ids = [rp() for _ in xrange(num_queries)]
+        ids.sort()
+        for id in ids:
+            world = Database.DbSession.query(World).get(id)
+            world.randomNumber = rp()
+            worlds.append(world.serialize())
+        Database.DbSession.commit()
+        output = json.dumps(worlds)
+        self.response()._headers["Content-Length"] = len(output)
+        self.write(output)

+ 33 - 0
frameworks/Python/historical/webware/app/Launch.py

@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+# You can pass several parameters on the command line
+# (more info by running this with option --help)
+# or you can modify the default values here
+# (more info in WebKit.Launch):
+import os
+
+workDir = None
+webwareDir = os.path.dirname(os.path.normpath(os.getcwd()))
+libraryDirs = ['Lib']
+runProfile = False
+logFile = None
+pidFile = None
+user = None
+group = None
+
+import sys
+sys.path.insert(0, webwareDir)
+
+from WebKit import Launch
+
+Launch.workDir = workDir
+Launch.webwareDir = webwareDir
+Launch.libraryDirs = libraryDirs
+Launch.runProfile = runProfile
+Launch.logFile = logFile
+Launch.pidFile = pidFile
+Launch.user = user
+Launch.group = group
+
+if __name__ == '__main__':
+    Launch.main()

+ 55 - 0
frameworks/Python/historical/webware/app/WebKit.cgi

@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+# If the Webware installation is located somewhere else,
+# then set the webwareDir variable to point to it here:
+webwareDir = '/home/knewman/Development/tfb-benchmark/webware/Webware'
+
+# If you used the MakeAppWorkDir.py script to make a separate
+# application working directory, specify it here:
+workDir = '/home/knewman/Development/tfb-benchmark/webware/Webware/WebwareTest'
+
+try:
+    import os, sys
+    if not webwareDir:
+        webwareDir = os.path.dirname(os.path.dirname(os.getcwd()))
+    sys.path.insert(1, webwareDir)
+    webKitDir = os.path.join(webwareDir, 'WebKit')
+    if workDir is None:
+        workDir = webKitDir
+    else:
+        sys.path.insert(1, workDir)
+    try:
+        import WebKit.Adapters.CGIAdapter
+    except ImportError:
+        if os.path.exists(webwareDir) and os.path.exists(webKitDir):
+            cgiAdapter = os.path.join(webKitDir, 'Adapters', 'CGIAdapter.py')
+            if os.path.exists(cgiAdapter):
+                raise
+            msg = "CGIAdapter module at <code>%s</code> cannot be loaded" % cgiAdapter
+        else:
+            msg = "Webware installation not found at <code>%s</code>" % webwareDir
+        sys.stdout.write('''Content-Type: text/html\n
+<html><head><title>WebKit CGI Error</title><body>
+<h3>WebKit CGI Error</h3>
+<p>%s.</p>
+<p>You may need to edit the WebKit.cgi script so that <code>webwareDir</code>
+points to the actual Webware installation directory.</p>
+<p>You may also need to modify permissions of the Webware installation
+with <code>chmod</code> so that the CGIAdapter module can be imported.</p>
+</body></html>\n''' % msg)
+    else:
+        WebKit.Adapters.CGIAdapter.main(workDir)
+except:
+    import sys, traceback
+    from time import asctime, localtime, time
+    sys.stderr.write('[%s] [error] WebKit: Error in adapter\n' % asctime(localtime(time())))
+    sys.stderr.write('Error while executing script\n')
+    traceback.print_exc(file=sys.stderr)
+    output = ''.join(traceback.format_exception(*sys.exc_info()))
+    output = output.replace('&', '&amp;').replace(
+        '<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
+    sys.stdout.write('''Content-Type: text/html\n
+<html><head><title>WebKit CGI Error</title><body>
+<h3>WebKit CGI Error</h3>
+<pre>%s</pre>
+</body></html>\n''' % output)

+ 1 - 0
frameworks/Python/historical/webware/app/adapter.address

@@ -0,0 +1 @@
+127.0.0.1:8086

+ 1 - 0
frameworks/Python/historical/webware/app/http.address

@@ -0,0 +1 @@
+127.0.0.1:8080

+ 171 - 0
frameworks/Python/historical/webware/app/webkit

@@ -0,0 +1,171 @@
+#!/bin/sh
+#
+# WebKit application server
+# part of Webware for Python
+# www.webwareforpython.org
+#
+# /etc/init.d/webkit
+#
+# init.d script for Debian GNU/Linux
+#
+
+### START LOCAL CONFIGURATION
+
+# If you store this script in your Webware working directory
+# and create a symlink to it as /etc/init.d/webkit_appname,
+# it will try to guess your configuration parameters. You can
+# make changes either directly here or you can also override
+# the configuration in the Launch.py script.
+
+# The name of your Webware application:
+APP_NAME=`basename "$0"`
+
+# Description of your Webware application:
+DESC="Webware"
+
+# The location of the start sript:
+if [ -h "$0" ]; then
+    # Get the target file if start script is given as a link:
+    START_SCRIPT=`readlink -f "$0"`
+else
+    START_SCRIPT="$0"
+fi
+
+# The working directory or path to WebKit:
+WORK_DIR=`dirname "$START_SCRIPT"`
+# Make sure to have the absolute path:
+test -d "$WORK_DIR" || exit 0
+WORK_DIR=`cd "$WORK_DIR" 2>/dev/null && pwd`
+
+# The app server launch script:
+APP_SERVER="$WORK_DIR/AppServer"
+test -x "$APP_SERVER" || exit 0
+
+# The app server configuration:
+APP_SERVER_CONFIG="$WORK_DIR/Configs/AppServer.config"
+test -f "$APP_SERVER_CONFIG" || exit 0
+
+# The WebKit app server log file
+# (you can set this in Launch.py as well):
+#LOG_FILE="/var/log/$APP_NAME.log"
+LOG_FILE="$WORK_DIR/Logs/webkit.log"
+# Use this extension if you want to move the last log away
+# (also consider using logrotate or something similar):
+LOG_OLD=".old"
+
+# The app server process id file
+# (you can set this in Launch.py as well):
+#PID_FILE="/var/run/$APP_NAME.pid"
+PID_FILE="$WORK_DIR/webkit.pid"
+
+# The user and group to run the app server
+# (you can set this in Launch.py as well).
+# If undefined, it will be the user and group
+# running the start script (usually root).
+# You should use a low-privilege account,
+# like the work dir owner, wwwrun or nobody.
+# This will use the owner of the AppServer script:
+WEBWARE_USER=`stat -c "%U" "$APP_SERVER"`
+WEBWARE_GROUP=`stat -c "%G" "$APP_SERVER"`
+
+# Unset the following variable if you want to store the
+# pid and log files as the user running the start script
+# (usually root) or set it if you want these files to be
+# written after switching to WEBWARE_USER:WEBWARE_GROUP.
+LAUNCH_AS_WEBWARE="yes"
+
+# Additional options -u or -O to be passed on to Python:
+PYTHONOPTS=
+# Additional libraries to be included in the Python path:
+PYTHONPATH=
+export PYTHONPATH
+
+### END LOCAL CONFIGURATION
+
+set -e
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+d_start() {
+    # Keep backup of last log file:
+    if [ "$LOG_OLD" -a -f "$LOG_FILE" ]; then
+        if [ -s "$LOG_FILE" ]; then
+            mv "$LOG_FILE" "$LOG_FILE$LOG_OLD"
+        else
+            rm "$LOG_FILE"
+        fi
+    fi
+    # Prepare option to set group
+    if [ "$WEBWARE_GROUP" ]; then
+        WEBWARE_GROUP="-g $WEBWARE_GROUP"
+    fi
+    # Note that the pid file does not record the pid of the
+    # wrapper script, but the pid of the Python app server:
+    if [ "$LAUNCH_AS_WEBWARE" ]; then
+        # Prepare option to set user
+        if [ "$WEBWARE_USER" ]; then
+            WEBWARE_USER="-c $WEBWARE_USER"
+        fi
+        # Switch user first, then create pid and log files:
+        start-stop-daemon -S -b -q -p "$PID_FILE" \
+            $WEBWARE_USER $WEBWARE_GROUP -a "$APP_SERVER" \
+            -- $PYTHONOPTS -d "$WORK_DIR" -o "$LOG_FILE" \
+            -i "$PID_FILE" > /dev/null
+
+    else
+        # Prepare option to set user
+        if [ "$WEBWARE_USER" ]; then
+            WEBWARE_USER="-u $WEBWARE_USER"
+        fi
+        # Create pid and log files first, then switch user:
+        start-stop-daemon -S -q -p "$PID_FILE" -a "$APP_SERVER" \
+            -- $PYTHONOPTS -d "$WORK_DIR" -i "$PID_FILE" \
+            $WEBWARE_USER $WEBWARE_GROUP >> "$LOG_FILE" 2>&1 &
+    fi
+}
+
+d_stop() {
+    # Note that we are terminating the Python app server here;
+    # the app server wrapper script will follow automatically:
+    [ -f "$PID_FILE" ] && \
+    start-stop-daemon -K -q -p $PID_FILE \
+        $WEBWARE_USER -n python
+    rm -f "$PID_FILE"
+}
+
+d_reload() {
+    [ -f "$PID_FILE" ] && \
+    start-stop-daemon -K -q -p $PID_FILE \
+        $WEBWARE_USER -n python -s HUP
+}
+
+case "$1" in
+    start)
+        echo -n "Starting $DESC: $APP_NAME"
+        d_start
+        echo "."
+        ;;
+    stop)
+        echo -n "Stopping $DESC: $APP_NAME"
+        d_stop
+        echo "."
+        ;;
+    reload|force-reload)
+        echo -n "Reloading $DESC configuration..."
+        d_reload
+        echo "done."
+        ;;
+    restart)
+        echo -n "Restarting $DESC: $NAME"
+        d_stop
+        sleep 1
+        d_start
+        echo "."
+        ;;
+    *)
+        echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
+        exit 1
+        ;;
+esac
+
+exit 0

+ 3 - 0
frameworks/Python/historical/webware/requirements.txt

@@ -0,0 +1,3 @@
+bleach==1.4.1
+mysqlclient==1.3.6
+SQLAlchemy==0.9.9

+ 9 - 0
frameworks/Python/historical/webware/setup.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+export PY2_ROOT=$IROOT/py2
+export PY2=$PY2_ROOT/bin/python
+
+cd $TROOT/webware/Webware-1.1.1
+$PY2 install.py --no-password-prompt 
+cd $TROOT/webware/Webware-1.1.1/app
+$PY2 Launch.py &