Browse Source

merge robfig-revel

Patrick Falls 12 years ago
parent
commit
2c1d869d5e

+ 1 - 1
config/benchmark_profile

@@ -3,7 +3,7 @@ export RESIN_HOME=~/FrameworkBenchmarks/installs/resin-4.0.34
 export GRAILS_HOME=~/FrameworkBenchmarks/installs/grails-2.1.1
 export VERTX_HOME=~/FrameworkBenchmarks/installs/vert.x-1.3.1.final
 export GOROOT=~/FrameworkBenchmarks/installs/go
-export GOPATH=~/FrameworkBenchmarks/go:~/FrameworkBenchmarks/webgo:$GOROOT
+export GOPATH=~/FrameworkBenchmarks/go:~/FrameworkBenchmarks/webgo:~/FrameworkBenchmarks/revel
 export TOMCAT_HOME=~/FrameworkBenchmarks/installs/apache-tomcat-7.0.35
 export NODE_HOME=~/FrameworkBenchmarks/installs/node-v0.10.2-linux-x64
 export PLAY_HOME=~/FrameworkBenchmarks/installs/play-2.1.1

+ 3 - 4
installer.py

@@ -26,7 +26,6 @@ class Installer:
     self.__run_command("sudo apt-get update", True)
     self.__run_command("sudo apt-get upgrade", True)    
     self.__run_command("sudo apt-get install build-essential libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev python-software-properties unzip git-core libcurl4-openssl-dev libbz2-dev libmysqlclient-dev mongodb-clients libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libgdbm-dev ncurses-dev automake libffi-dev htop libtool bison libevent-dev libgstreamer-plugins-base0.10-0 libgstreamer0.10-0 liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev libjson0-dev libmcrypt-dev libicu-dev cmake gettext", True)
-
     self.__run_command("cp ../config/benchmark_profile ../../.bash_profile")
     self.__run_command("sudo sh -c \"echo '*               soft    nofile          8192' >> /etc/security/limits.conf\"")
 
@@ -100,7 +99,7 @@ class Installer:
     #
     # go
     #
-    
+
     self.__run_command("curl http://go.googlecode.com/files/go1.1rc1.linux-amd64.tar.gz | tar xvz")
 
     #
@@ -375,14 +374,14 @@ class Installer:
 
     # Insert data
     mysql -uroot -psecret < create.sql
-    
+
     ##############################
     # Postgres
     ##############################
     sudo useradd benchmarkdbuser -p benchmarkdbpass
     sudo -u postgres psql template1 < create-postgres-database.sql
     sudo -u benchmarkdbuser psql hello_world < create-postgres.sql
-    
+
     sudo mv postgresql.conf /etc/postgresql/9.1/main/postgresql.conf
     sudo mv pg_hba.conf /etc/postgresql/9.1/main/pg_hba.conf
     sudo -u postgres -H /etc/init.d/postgresql restart

+ 0 - 0
revel/__init__.py


+ 14 - 0
revel/benchmark_config

@@ -0,0 +1,14 @@
+{
+  "framework": "revel",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "fortune_url": "/fortune",
+      "port": 8080,
+      "sort": 90
+    }
+  }]
+}

+ 21 - 0
revel/setup.py

@@ -0,0 +1,21 @@
+import subprocess
+import sys
+import os
+import setup_util
+import time
+
+def start(args):
+  setup_util.replace_text("revel/src/benchmark/conf/app.conf", "tcp\(.*:3306\)", "tcp(" + args.database_host + ":3306)")
+  subprocess.call("go get github.com/robfig/revel/cmd", shell=True, cwd="revel")
+  subprocess.call("go build -o bin/revel github.com/robfig/revel/cmd", shell=True, cwd="revel")
+  subprocess.Popen("bin/revel run benchmark prod".rsplit(" "), cwd="revel")
+  return 0
+
+def stop():
+  p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+  out, err = p.communicate()
+  for line in out.splitlines():
+    if 'revel' in line:
+      pid = int(line.split(None, 2)[1])
+      os.kill(pid, 9)
+  return 0

+ 3 - 0
revel/src/benchmark/.gitignore

@@ -0,0 +1,3 @@
+test-results/
+tmp/
+routes/

+ 119 - 0
revel/src/benchmark/app/controllers/app.go

@@ -0,0 +1,119 @@
+package controllers
+
+import (
+	"database/sql"
+	// _ "github.com/go-sql-driver/mysql"
+	"github.com/robfig/revel"
+	"github.com/robfig/revel/modules/db/app"
+	"math/rand"
+	"runtime"
+	"sort"
+	"sync"
+)
+
+type MessageStruct struct {
+	Message string `json:"message"`
+}
+
+type World struct {
+	Id           uint16 `json:"id"`
+	RandomNumber uint16 `json:"randomNumber"`
+}
+
+type Fortune struct {
+	Id      uint16 `json:"id"`
+	Message string `json:"message"`
+}
+
+const (
+	WorldSelect        = "SELECT id,randomNumber FROM World where id=?"
+	FortuneSelect      = "SELECT id,message FROM Fortune"
+	WorldRowCount      = 10000
+	MaxConnectionCount = 100
+)
+
+var (
+	worldStatement   *sql.Stmt
+	fortuneStatement *sql.Stmt
+)
+
+func init() {
+	revel.OnAppStart(func() {
+		var err error
+		runtime.GOMAXPROCS(runtime.NumCPU())
+		db.DbPlugin{}.OnAppStart()
+		db.Db.SetMaxIdleConns(MaxConnectionCount)
+		if worldStatement, err = db.Db.Prepare(WorldSelect); err != nil {
+			revel.ERROR.Fatalln(err)
+		}
+		if fortuneStatement, err = db.Db.Prepare(FortuneSelect); err != nil {
+			revel.ERROR.Fatalln(err)
+		}
+	})
+}
+
+type App struct {
+	*revel.Controller
+}
+
+func (c App) Json() revel.Result {
+	c.Response.ContentType = "application/json"
+	return c.RenderJson(MessageStruct{"Hello, world"})
+}
+
+func (c App) Db(queries int) revel.Result {
+	rowNum := rand.Intn(WorldRowCount) + 1
+	if queries <= 1 {
+		var w World
+		worldStatement.QueryRow(rowNum).Scan(&w.Id, &w.RandomNumber)
+		return c.RenderJson(w)
+	}
+
+	ww := make([]World, queries)
+	var wg sync.WaitGroup
+	wg.Add(queries)
+	for i := 0; i < queries; i++ {
+		go func(i int) {
+			err := worldStatement.QueryRow(rowNum).Scan(&ww[i].Id, &ww[i].RandomNumber)
+			if err != nil {
+				revel.ERROR.Fatalf("Error scanning world row: %v", err)
+			}
+			wg.Done()
+		}(i)
+	}
+	wg.Wait()
+	return c.RenderJson(ww)
+}
+
+func (c App) Fortune() revel.Result {
+	fortunes := make([]*Fortune, 0, 16)
+
+	rows, err := fortuneStatement.Query()
+	if err != nil {
+		revel.ERROR.Fatalf("Error preparing statement: %v", err)
+	}
+
+	i := 0
+	var fortune *Fortune
+	for rows.Next() {
+		fortune = new(Fortune)
+		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
+			revel.ERROR.Fatalf("Error scanning fortune row: %v", err)
+		}
+		fortunes = append(fortunes, fortune)
+		i++
+	}
+	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})
+
+	sort.Sort(ByMessage{fortunes})
+	return c.Render(fortunes)
+}
+
+type Fortunes []*Fortune
+
+func (s Fortunes) Len() int      { return len(s) }
+func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+type ByMessage struct{ Fortunes }
+
+func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }

+ 14 - 0
revel/src/benchmark/app/views/App/Fortune.html

@@ -0,0 +1,14 @@
+{{template "header.html" .}}
+<table>
+<tr>
+<th>id</th>
+<th>message</th>
+</tr>
+{{range .fortunes}}
+<tr>
+<td>{{.Id}}</td>
+<td>{{.Message}}</td>
+</tr>
+{{end}}
+</table>
+{{template "footer.html" .}}

+ 2 - 0
revel/src/benchmark/app/views/footer.html

@@ -0,0 +1,2 @@
+</body>
+</html>

+ 6 - 0
revel/src/benchmark/app/views/header.html

@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>

+ 28 - 0
revel/src/benchmark/conf/app.conf

@@ -0,0 +1,28 @@
+app.name=benchmark
+http.addr=
+http.port=8080
+
+db.driver = mysql
+db.import = github.com/go-sql-driver/mysql
+db.spec = benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?charset=utf8
+
+results.pretty=false
+results.chunked=false
+
+[dev]
+mode.dev=true
+watch=true
+
+log.trace.output = stderr
+log.info.output  = stderr
+log.warn.output  = stderr
+log.error.output = stderr
+
+[prod]
+mode.dev=false
+watch=false
+
+log.trace.output = off
+log.info.output  = off
+log.warn.output  = %(app.name)s.log
+log.error.output = %(app.name)s.log

+ 7 - 0
revel/src/benchmark/conf/routes

@@ -0,0 +1,7 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+
+GET     /db                                     App.Db
+GET     /json                                   App.Json
+GET     /fortune                                App.Fortune