Browse Source

fasthttp: switch from html/template to github.com/valyala/quicktemplate

Aliaksandr Valialkin 9 years ago
parent
commit
4a1cf30c24

+ 9 - 16
frameworks/Go/fasthttp-mysql/src/hello/hello.go → frameworks/Go/fasthttp-mysql/server.go

@@ -1,10 +1,10 @@
+//go:generate qtc -dir=templates
 package main
 package main
 
 
 import (
 import (
 	"database/sql"
 	"database/sql"
 	"encoding/json"
 	"encoding/json"
 	"flag"
 	"flag"
-	"html/template"
 	"log"
 	"log"
 	"math/rand"
 	"math/rand"
 	"net"
 	"net"
@@ -17,6 +17,8 @@ import (
 	_ "github.com/go-sql-driver/mysql"
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp/reuseport"
 	"github.com/valyala/fasthttp/reuseport"
+
+	"./templates"
 )
 )
 
 
 type JSONResponse struct {
 type JSONResponse struct {
@@ -28,11 +30,6 @@ type World struct {
 	RandomNumber uint16 `json:"randomNumber"`
 	RandomNumber uint16 `json:"randomNumber"`
 }
 }
 
 
-type Fortune struct {
-	Id      uint16 `json:"id"`
-	Message string `json:"message"`
-}
-
 const (
 const (
 	connectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world"
 	connectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world"
 	worldRowCount      = 10000
 	worldRowCount      = 10000
@@ -48,8 +45,6 @@ var (
 const helloWorldString = "Hello, World!"
 const helloWorldString = "Hello, World!"
 
 
 var (
 var (
-	tmpl = template.Must(template.ParseFiles("templates/fortune.html"))
-
 	db *sql.DB
 	db *sql.DB
 
 
 	helloWorldBytes = []byte(helloWorldString)
 	helloWorldBytes = []byte(helloWorldString)
@@ -153,23 +148,21 @@ func fortuneHandler(ctx *fasthttp.RequestCtx) {
 		log.Fatalf("Error selecting db data: %v", err)
 		log.Fatalf("Error selecting db data: %v", err)
 	}
 	}
 
 
-	fortunes := make([]Fortune, 0, 16)
+	fortunes := make([]templates.Fortune, 0, 16)
 	for rows.Next() {
 	for rows.Next() {
-		var f Fortune
-		if err := rows.Scan(&f.Id, &f.Message); err != nil {
+		var f templates.Fortune
+		if err := rows.Scan(&f.ID, &f.Message); err != nil {
 			log.Fatalf("Error scanning fortune row: %s", err)
 			log.Fatalf("Error scanning fortune row: %s", err)
 		}
 		}
 		fortunes = append(fortunes, f)
 		fortunes = append(fortunes, f)
 	}
 	}
 	rows.Close()
 	rows.Close()
-	fortunes = append(fortunes, Fortune{Message: "Additional fortune added at request time."})
+	fortunes = append(fortunes, templates.Fortune{Message: "Additional fortune added at request time."})
 
 
 	sort.Sort(FortunesByMessage(fortunes))
 	sort.Sort(FortunesByMessage(fortunes))
 
 
 	ctx.SetContentType("text/html; charset=utf-8")
 	ctx.SetContentType("text/html; charset=utf-8")
-	if err := tmpl.Execute(ctx, fortunes); err != nil {
-		log.Fatalf("Error executing fortune: %s", err)
-	}
+	templates.WriteFortunePage(ctx, fortunes)
 }
 }
 
 
 // Test 5: Database updates
 // Test 5: Database updates
@@ -236,7 +229,7 @@ func getQueriesCount(ctx *fasthttp.RequestCtx) int {
 	return n
 	return n
 }
 }
 
 
-type FortunesByMessage []Fortune
+type FortunesByMessage []templates.Fortune
 
 
 func (s FortunesByMessage) Len() int           { return len(s) }
 func (s FortunesByMessage) Len() int           { return len(s) }
 func (s FortunesByMessage) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 func (s FortunesByMessage) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

+ 2 - 1
frameworks/Go/fasthttp-mysql/setup.bat

@@ -1,2 +1,3 @@
 set GOPATH=C:\FrameworkBenchmarks\Go\fasthttp-mysql
 set GOPATH=C:\FrameworkBenchmarks\Go\fasthttp-mysql
-go run src\hello\hello.go
+go build -o server
+.\server

+ 5 - 4
frameworks/Go/fasthttp-mysql/setup.sh

@@ -1,12 +1,13 @@
 #!/bin/bash
 #!/bin/bash
 
 
-sed -i 's|tcp(.*:3306)|tcp('"${DBHOST}"':3306)|g' src/hello/hello.go
+sed -i 's|tcp(.*:3306)|tcp('"${DBHOST}"':3306)|g' server.go
 
 
 fw_depends go
 fw_depends go
 
 
 go get -u github.com/go-sql-driver/mysql
 go get -u github.com/go-sql-driver/mysql
 go get -u github.com/valyala/fasthttp
 go get -u github.com/valyala/fasthttp
+go get -u github.com/valyala/quicktemplate/...
 
 
-rm -f ./hello
-go build src/hello/hello.go
-./hello &
+rm -f ./server
+go build -o server
+./server &

+ 5 - 4
frameworks/Go/fasthttp-mysql/setup_prefork.sh

@@ -1,12 +1,13 @@
 #!/bin/bash
 #!/bin/bash
 
 
-sed -i 's|tcp(.*:3306)|tcp('"${DBHOST}"':3306)|g' src/hello/hello.go
+sed -i 's|tcp(.*:3306)|tcp('"${DBHOST}"':3306)|g' server.go
 
 
 fw_depends go
 fw_depends go
 
 
 go get -u github.com/go-sql-driver/mysql
 go get -u github.com/go-sql-driver/mysql
 go get -u github.com/valyala/fasthttp
 go get -u github.com/valyala/fasthttp
+go get -u github.com/valyala/quicktemplate/...
 
 
-rm -f ./hello
-go build src/hello/hello.go
-./hello -prefork &
+rm -f ./server
+go build -o server
+./server -prefork &

+ 3 - 4
frameworks/Go/fasthttp-mysql/source_code

@@ -1,5 +1,4 @@
-./fasthttp-mysql/src/
-./fasthttp-mysql/src/hello
-./fasthttp-mysql/src/hello/hello.go
+./fasthttp-mysql/server.go
 ./fasthttp-mysql/templates/
 ./fasthttp-mysql/templates/
-./fasthttp-mysql/templates/fortune.html
+./fasthttp-mysql/templates/fortune.qtpl
+./fasthttp-mysql/templates/fortune.qtpl.go

+ 0 - 14
frameworks/Go/fasthttp-mysql/templates/fortune.html

@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Fortunes</title>
-</head>
-<body>
-<table>
-<tr><th>id</th><th>message</th></tr>
-{{range .}}
-<tr><td>{{.Id}}</td><td>{{.Message}}</td></tr>
-{{end}}
-</table>
-</body>
-</html>

+ 23 - 0
frameworks/Go/fasthttp-mysql/templates/fortune.qtpl

@@ -0,0 +1,23 @@
+{% code
+type Fortune struct {
+	ID int
+	Message string
+}
+%}
+
+{% func FortunePage(rows []Fortune) %}
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+{% for _, r := range rows %}
+<tr><td>{%d r.ID %}</td><td>{%s r.Message %}</td></tr>
+{% endfor %}
+</table>
+</body>
+</html>
+{% endfunc %}

+ 88 - 0
frameworks/Go/fasthttp-mysql/templates/fortune.qtpl.go

@@ -0,0 +1,88 @@
+// This file is automatically generated by qtc from "fortune.qtpl".
+// See https://github.com/valyala/quicktemplate for details.
+
+//line templates/fortune.qtpl:1
+package templates
+
+//line templates/fortune.qtpl:1
+import (
+	"io"
+
+	"github.com/valyala/quicktemplate"
+)
+
+//line templates/fortune.qtpl:1
+var (
+	_ = io.Copy
+	_ = quicktemplate.AcquireByteBuffer
+)
+
+//line templates/fortune.qtpl:2
+type Fortune struct {
+	ID      int
+	Message string
+}
+
+//line templates/fortune.qtpl:8
+func StreamFortunePage(qw *quicktemplate.Writer, rows []Fortune) {
+	//line templates/fortune.qtpl:8
+	qw.N().S(`
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+`)
+	//line templates/fortune.qtpl:17
+	for _, r := range rows {
+		//line templates/fortune.qtpl:17
+		qw.N().S(`
+<tr><td>`)
+		//line templates/fortune.qtpl:18
+		qw.N().D(r.ID)
+		//line templates/fortune.qtpl:18
+		qw.N().S(`</td><td>`)
+		//line templates/fortune.qtpl:18
+		qw.E().S(r.Message)
+		//line templates/fortune.qtpl:18
+		qw.N().S(`</td></tr>
+`)
+		//line templates/fortune.qtpl:19
+	}
+	//line templates/fortune.qtpl:19
+	qw.N().S(`
+</table>
+</body>
+</html>
+`)
+//line templates/fortune.qtpl:23
+}
+
+//line templates/fortune.qtpl:23
+func WriteFortunePage(qww io.Writer, rows []Fortune) {
+	//line templates/fortune.qtpl:23
+	qw := quicktemplate.AcquireWriter(qww)
+	//line templates/fortune.qtpl:23
+	StreamFortunePage(qw, rows)
+	//line templates/fortune.qtpl:23
+	quicktemplate.ReleaseWriter(qw)
+//line templates/fortune.qtpl:23
+}
+
+//line templates/fortune.qtpl:23
+func FortunePage(rows []Fortune) string {
+	//line templates/fortune.qtpl:23
+	qb := quicktemplate.AcquireByteBuffer()
+	//line templates/fortune.qtpl:23
+	WriteFortunePage(qb, rows)
+	//line templates/fortune.qtpl:23
+	qs := string(qb.B)
+	//line templates/fortune.qtpl:23
+	quicktemplate.ReleaseByteBuffer(qb)
+	//line templates/fortune.qtpl:23
+	return qs
+//line templates/fortune.qtpl:23
+}

+ 9 - 16
frameworks/Go/fasthttp-postgresql/src/hello/hello.go → frameworks/Go/fasthttp-postgresql/server.go

@@ -1,10 +1,10 @@
+//go:generate qtc -dir=templates
 package main
 package main
 
 
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
-	"html/template"
 	"log"
 	"log"
 	"math/rand"
 	"math/rand"
 	"net"
 	"net"
@@ -17,6 +17,8 @@ import (
 	"github.com/jackc/pgx"
 	"github.com/jackc/pgx"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp/reuseport"
 	"github.com/valyala/fasthttp/reuseport"
+
+	"./templates"
 )
 )
 
 
 type JSONResponse struct {
 type JSONResponse struct {
@@ -28,11 +30,6 @@ type World struct {
 	RandomNumber int32 `json:"randomNumber"`
 	RandomNumber int32 `json:"randomNumber"`
 }
 }
 
 
-type Fortune struct {
-	Id      int32  `json:"id"`
-	Message string `json:"message"`
-}
-
 const (
 const (
 	worldRowCount      = 10000
 	worldRowCount      = 10000
 	maxConnectionCount = 40
 	maxConnectionCount = 40
@@ -47,8 +44,6 @@ var (
 const helloWorldString = "Hello, World!"
 const helloWorldString = "Hello, World!"
 
 
 var (
 var (
-	tmpl = template.Must(template.ParseFiles("templates/fortune.html"))
-
 	db *pgx.ConnPool
 	db *pgx.ConnPool
 
 
 	helloWorldBytes = []byte(helloWorldString)
 	helloWorldBytes = []byte(helloWorldString)
@@ -144,23 +139,21 @@ func fortuneHandler(ctx *fasthttp.RequestCtx) {
 		log.Fatalf("Error selecting db data: %v", err)
 		log.Fatalf("Error selecting db data: %v", err)
 	}
 	}
 
 
-	fortunes := make([]Fortune, 0, 16)
+	fortunes := make([]templates.Fortune, 0, 16)
 	for rows.Next() {
 	for rows.Next() {
-		var f Fortune
-		if err := rows.Scan(&f.Id, &f.Message); err != nil {
+		var f templates.Fortune
+		if err := rows.Scan(&f.ID, &f.Message); err != nil {
 			log.Fatalf("Error scanning fortune row: %s", err)
 			log.Fatalf("Error scanning fortune row: %s", err)
 		}
 		}
 		fortunes = append(fortunes, f)
 		fortunes = append(fortunes, f)
 	}
 	}
 	rows.Close()
 	rows.Close()
-	fortunes = append(fortunes, Fortune{Message: "Additional fortune added at request time."})
+	fortunes = append(fortunes, templates.Fortune{Message: "Additional fortune added at request time."})
 
 
 	sort.Sort(FortunesByMessage(fortunes))
 	sort.Sort(FortunesByMessage(fortunes))
 
 
 	ctx.SetContentType("text/html; charset=utf-8")
 	ctx.SetContentType("text/html; charset=utf-8")
-	if err := tmpl.Execute(ctx, fortunes); err != nil {
-		log.Fatalf("Error executing fortune: %s", err)
-	}
+	templates.WriteFortunePage(ctx, fortunes)
 }
 }
 
 
 // Test 5: Database updates
 // Test 5: Database updates
@@ -228,7 +221,7 @@ func getQueriesCount(ctx *fasthttp.RequestCtx) int {
 	return n
 	return n
 }
 }
 
 
-type FortunesByMessage []Fortune
+type FortunesByMessage []templates.Fortune
 
 
 func (s FortunesByMessage) Len() int           { return len(s) }
 func (s FortunesByMessage) Len() int           { return len(s) }
 func (s FortunesByMessage) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 func (s FortunesByMessage) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

+ 2 - 1
frameworks/Go/fasthttp-postgresql/setup.bat

@@ -1,2 +1,3 @@
 set GOPATH=C:\FrameworkBenchmarks\Go\fasthttp-postgresql
 set GOPATH=C:\FrameworkBenchmarks\Go\fasthttp-postgresql
-go run src\hello\hello.go
+go build -o server
+.\server

+ 5 - 4
frameworks/Go/fasthttp-postgresql/setup.sh

@@ -1,12 +1,13 @@
 #!/bin/bash
 #!/bin/bash
 
 
-sed -i 's|localhost|'"${DBHOST}"'|g' src/hello/hello.go
+sed -i 's|localhost|'"${DBHOST}"'|g' server.go
 
 
 fw_depends go
 fw_depends go
 
 
 go get -u github.com/jackc/pgx
 go get -u github.com/jackc/pgx
 go get -u github.com/valyala/fasthttp
 go get -u github.com/valyala/fasthttp
+go get -u github.com/valyala/quicktemplate/...
 
 
-rm -f ./hello
-go build src/hello/hello.go
-./hello &
+rm -f ./server
+go build -o server
+./server &

+ 5 - 4
frameworks/Go/fasthttp-postgresql/setup_prefork.sh

@@ -1,12 +1,13 @@
 #!/bin/bash
 #!/bin/bash
 
 
-sed -i 's|localhost|'"${DBHOST}"'|g' src/hello/hello.go
+sed -i 's|localhost|'"${DBHOST}"'|g' server.go
 
 
 fw_depends go
 fw_depends go
 
 
 go get -u github.com/jackc/pgx
 go get -u github.com/jackc/pgx
 go get -u github.com/valyala/fasthttp
 go get -u github.com/valyala/fasthttp
+go get -u github.com/valyala/quicktemplate/...
 
 
-rm -f ./hello
-go build src/hello/hello.go
-./hello -prefork &
+rm -f ./server
+go build -o server
+./server -prefork &

+ 3 - 4
frameworks/Go/fasthttp-postgresql/source_code

@@ -1,5 +1,4 @@
-./fasthttp-postgresql/src/
-./fasthttp-postgresql/src/hello
-./fasthttp-postgresql/src/hello/hello.go
+./fasthttp-postgresql/server.go
 ./fasthttp-postgresql/templates/
 ./fasthttp-postgresql/templates/
-./fasthttp-postgresql/templates/fortune.html
+./fasthttp-postgresql/templates/fortune.qtpl
+./fasthttp-postgresql/templates/fortune.qtpl.go

+ 0 - 14
frameworks/Go/fasthttp-postgresql/templates/fortune.html

@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Fortunes</title>
-</head>
-<body>
-<table>
-<tr><th>id</th><th>message</th></tr>
-{{range .}}
-<tr><td>{{.Id}}</td><td>{{.Message}}</td></tr>
-{{end}}
-</table>
-</body>
-</html>

+ 23 - 0
frameworks/Go/fasthttp-postgresql/templates/fortune.qtpl

@@ -0,0 +1,23 @@
+{% code
+type Fortune struct {
+	ID int32
+	Message string
+}
+%}
+
+{% func FortunePage(rows []Fortune) %}
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+{% for _, r := range rows %}
+<tr><td>{%d int(r.ID) %}</td><td>{%s r.Message %}</td></tr>
+{% endfor %}
+</table>
+</body>
+</html>
+{% endfunc %}

+ 88 - 0
frameworks/Go/fasthttp-postgresql/templates/fortune.qtpl.go

@@ -0,0 +1,88 @@
+// This file is automatically generated by qtc from "fortune.qtpl".
+// See https://github.com/valyala/quicktemplate for details.
+
+//line templates/fortune.qtpl:1
+package templates
+
+//line templates/fortune.qtpl:1
+import (
+	"io"
+
+	"github.com/valyala/quicktemplate"
+)
+
+//line templates/fortune.qtpl:1
+var (
+	_ = io.Copy
+	_ = quicktemplate.AcquireByteBuffer
+)
+
+//line templates/fortune.qtpl:2
+type Fortune struct {
+	ID      int32
+	Message string
+}
+
+//line templates/fortune.qtpl:8
+func StreamFortunePage(qw *quicktemplate.Writer, rows []Fortune) {
+	//line templates/fortune.qtpl:8
+	qw.N().S(`
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+`)
+	//line templates/fortune.qtpl:17
+	for _, r := range rows {
+		//line templates/fortune.qtpl:17
+		qw.N().S(`
+<tr><td>`)
+		//line templates/fortune.qtpl:18
+		qw.N().D(int(r.ID))
+		//line templates/fortune.qtpl:18
+		qw.N().S(`</td><td>`)
+		//line templates/fortune.qtpl:18
+		qw.E().S(r.Message)
+		//line templates/fortune.qtpl:18
+		qw.N().S(`</td></tr>
+`)
+		//line templates/fortune.qtpl:19
+	}
+	//line templates/fortune.qtpl:19
+	qw.N().S(`
+</table>
+</body>
+</html>
+`)
+//line templates/fortune.qtpl:23
+}
+
+//line templates/fortune.qtpl:23
+func WriteFortunePage(qww io.Writer, rows []Fortune) {
+	//line templates/fortune.qtpl:23
+	qw := quicktemplate.AcquireWriter(qww)
+	//line templates/fortune.qtpl:23
+	StreamFortunePage(qw, rows)
+	//line templates/fortune.qtpl:23
+	quicktemplate.ReleaseWriter(qw)
+//line templates/fortune.qtpl:23
+}
+
+//line templates/fortune.qtpl:23
+func FortunePage(rows []Fortune) string {
+	//line templates/fortune.qtpl:23
+	qb := quicktemplate.AcquireByteBuffer()
+	//line templates/fortune.qtpl:23
+	WriteFortunePage(qb, rows)
+	//line templates/fortune.qtpl:23
+	qs := string(qb.B)
+	//line templates/fortune.qtpl:23
+	quicktemplate.ReleaseByteBuffer(qb)
+	//line templates/fortune.qtpl:23
+	return qs
+//line templates/fortune.qtpl:23
+}