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/luminus"
     - "TESTDIR=Clojure/pedestal"
+    - "TESTDIR=Clojure/aleph"
     - "TESTDIR=D/vibed"
     - "TESTDIR=Dart/dart"
     - "TESTDIR=Dart/dart-redstone"
@@ -127,6 +128,7 @@ env:
     - "TESTDIR=Python/django"
     - "TESTDIR=Python/falcon"
     - "TESTDIR=Python/flask"
+    - "TESTDIR=Python/historical"
     - "TESTDIR=Python/klein"
     - "TESTDIR=Python/pyramid"
     - "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": [{
     "default": {
       "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,
       "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",
       "framework": "luminus",
       "language": "Clojure",
       "orm": "Raw",
-      "platform": "Servlet",
-      "webserver": "Resin",
+      "platform": "http-kit",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "luminus",
       "notes": "",
-      "versus": "servlet"
+      "versus": ""
     }
   }]
 }

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

@@ -5,7 +5,6 @@
 pom.xml
 *.jar
 *.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
 
-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
-  {: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 %}
 
@@ -13,6 +13,6 @@
     <td>{{message.message}}</td>
   </tr>
   {% endfor %}
-</table>  
-  
+</table>
+
 {% 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
-  (: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]
             [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
   "init will be called once when
@@ -24,34 +24,34 @@
   []
   (timbre/set-config!
     [: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
-     :fn rotor/appender-fn})
+     :fn                    rotor/appender-fn})
 
   (timbre/set-config!
     [: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
   "destroy will be called when your application
    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
-  (: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
   "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"
-  (response/json (first (run-queries 1))))
-
+  []
+  (-> 1 db/run-queries first response))
 
 (defn multiple-query-test
   "Test 3: Multiple database query"
   [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"
-  (layout/render "home.html"
-                 {:messages get-fortunes}))
-
+  []
+  (layout/render "home.html" {:messages (db/get-fortunes)}))
 
 (defn db-update
   "Test 5: Database updates"
   [queries]
   (-> queries
-      (get-query-count)
-      (update-and-persist)
-      (response/json)))
-
+      db/update-and-persist
+      response))
 
 (def plaintext
   "Test 6: Plaintext"
   {:status 200
-   :headers {"Content-Type" "text/plain; charset=utf-8"}
+   :headers {"Content-Type" "text/plain"}
    :body "Hello, World!"})
 
-
 (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
   (testing "main route"
     (let [response (app (request :get "/"))]
-      (is (= (:status response) 200))
-      (is (= (:body response)
-             "Hello, World!"))))
+      (is (= 200 (:status response)))))
 
   (testing "not-found route"
     (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
-
 source $IROOT/java7.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
 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/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/public
 ./luminus/hello/resources/public/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/hello
 ./luminus/hello/test/hello/test
 ./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 &