Browse Source

[Go/fasthttp] Upgrade fasthttp to v1.14.0, remove some tests and refactor (#5774)

* Upgrade fasthttp to v1.14.0, remove some tests and refactor

* Fix typo
Sergio Andrés Virviescas Santana 5 years ago
parent
commit
f26be1c79e
32 changed files with 272 additions and 1334 deletions
  1. 0 162
      frameworks/Go/fasthttp/benchmark_config.json
  2. 0 15
      frameworks/Go/fasthttp/fasthttp-easyjson-prefork.dockerfile
  3. 0 15
      frameworks/Go/fasthttp/fasthttp-easyjson.dockerfile
  4. 0 15
      frameworks/Go/fasthttp/fasthttp-mongo-prefork.dockerfile
  5. 0 15
      frameworks/Go/fasthttp/fasthttp-mongo.dockerfile
  6. 0 15
      frameworks/Go/fasthttp/fasthttp-prefork-quicktemplate.dockerfile
  7. 1 4
      frameworks/Go/fasthttp/fasthttp-prefork.dockerfile
  8. 0 15
      frameworks/Go/fasthttp/fasthttp-quicktemplate.dockerfile
  9. 0 15
      frameworks/Go/fasthttp/fasthttp-sjson-prefork.dockerfile
  10. 0 15
      frameworks/Go/fasthttp/fasthttp-sjson.dockerfile
  11. 1 4
      frameworks/Go/fasthttp/fasthttp.dockerfile
  12. 2 5
      frameworks/Go/fasthttp/src/go.mod
  13. 4 82
      frameworks/Go/fasthttp/src/go.sum
  14. 45 0
      frameworks/Go/fasthttp/src/handlers/db.go
  15. 86 91
      frameworks/Go/fasthttp/src/handlers/handlers.go
  16. 0 74
      frameworks/Go/fasthttp/src/handlers/handlers_easyjson.go
  17. 0 74
      frameworks/Go/fasthttp/src/handlers/handlers_sjson.go
  18. 5 27
      frameworks/Go/fasthttp/src/handlers/message.go
  19. 0 85
      frameworks/Go/fasthttp/src/handlers/message_easyjson.go
  20. 14 0
      frameworks/Go/fasthttp/src/handlers/types.go
  21. 24 0
      frameworks/Go/fasthttp/src/handlers/utils.go
  22. 38 0
      frameworks/Go/fasthttp/src/handlers/world.go
  23. 19 65
      frameworks/Go/fasthttp/src/main.go
  24. 0 43
      frameworks/Go/fasthttp/src/storage/db.go
  25. 0 108
      frameworks/Go/fasthttp/src/storage/mongo.go
  26. 0 86
      frameworks/Go/fasthttp/src/storage/pgx.go
  27. 0 85
      frameworks/Go/fasthttp/src/storage/world.go
  28. 0 158
      frameworks/Go/fasthttp/src/storage/world_easyjson.go
  29. 19 57
      frameworks/Go/fasthttp/src/templates/fortune.go
  30. 1 1
      frameworks/Go/fasthttp/src/templates/fortunes.qtpl
  31. 3 3
      frameworks/Go/fasthttp/src/templates/fortunes.qtpl.go
  32. 10 0
      frameworks/Go/fasthttp/src/templates/types.go

+ 0 - 162
frameworks/Go/fasthttp/benchmark_config.json

@@ -47,168 +47,6 @@
         "display_name": "fasthttp",
         "display_name": "fasthttp",
         "notes": "",
         "notes": "",
         "versus": "go"
         "versus": "go"
-      },
-      "easyjson": {
-        "json_url": "/json",
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "easyjson-prefork": {
-        "json_url": "/json",
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "sjson": {
-        "json_url": "/json",
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "sjson-prefork": {
-        "json_url": "/json",
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "quicktemplate": {
-        "fortune_url": "/fortune",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "prefork-quicktemplate": {
-        "fortune_url": "/fortune",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "Postgres",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "mongo": {
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "fortune_url": "/fortune",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "MongoDB",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
-      },
-      "mongo-prefork": {
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "fortune_url": "/fortune",
-        "update_url": "/update?queries=",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Platform",
-        "database": "MongoDB",
-        "framework": "None",
-        "language": "Go",
-        "flavor": "None",
-        "orm": "Raw",
-        "platform": "None",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "fasthttp",
-        "notes": "",
-        "versus": "go"
       }
       }
     }
     }
   ]
   ]

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-easyjson-prefork.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db pgx -json_encoder easyjson -prefork

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-easyjson.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db pgx -json_encoder easyjson

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-mongo-prefork.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db mongo -db_connection_string "mongodb://tfb-database" -prefork

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-mongo.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db mongo -db_connection_string "mongodb://tfb-database"

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-prefork-quicktemplate.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -prefork -db pgx -quicktemplate

+ 1 - 4
frameworks/Go/fasthttp/fasthttp-prefork.dockerfile

@@ -5,11 +5,8 @@ WORKDIR /fasthttp
 COPY ./src /fasthttp
 COPY ./src /fasthttp
 
 
 RUN go get github.com/valyala/quicktemplate/qtc
 RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
 
 
 RUN go generate ./templates
 RUN go generate ./templates
-RUN easyjson -pkg
 RUN go build -ldflags="-s -w" -o app .
 RUN go build -ldflags="-s -w" -o app .
 
 
-CMD ./app -prefork -db pgx
+CMD ./app -prefork

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-quicktemplate.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db pgx -quicktemplate

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-sjson-prefork.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db pgx -json_encoder sjson -prefork

+ 0 - 15
frameworks/Go/fasthttp/fasthttp-sjson.dockerfile

@@ -1,15 +0,0 @@
-FROM golang:1.14
-
-WORKDIR /fasthttp
-
-COPY ./src /fasthttp
-
-RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
-
-RUN go generate ./templates
-RUN easyjson -pkg
-RUN go build -ldflags="-s -w" -o app .
-
-CMD ./app -db pgx -json_encoder sjson

+ 1 - 4
frameworks/Go/fasthttp/fasthttp.dockerfile

@@ -5,11 +5,8 @@ WORKDIR /fasthttp
 COPY ./src /fasthttp
 COPY ./src /fasthttp
 
 
 RUN go get github.com/valyala/quicktemplate/qtc
 RUN go get github.com/valyala/quicktemplate/qtc
-RUN go get -u github.com/mailru/easyjson/...
-RUN go mod download
 
 
 RUN go generate ./templates
 RUN go generate ./templates
-RUN easyjson -pkg
 RUN go build -ldflags="-s -w" -o app .
 RUN go build -ldflags="-s -w" -o app .
 
 
-CMD ./app -db pgx
+CMD ./app

+ 2 - 5
frameworks/Go/fasthttp/src/go.mod

@@ -4,10 +4,7 @@ go 1.14
 
 
 require (
 require (
 	github.com/jackc/pgx/v4 v4.6.0
 	github.com/jackc/pgx/v4 v4.6.0
-	github.com/mailru/easyjson v0.7.1
-	github.com/savsgio/gotils v0.0.0-20200413113635-8c468ce75cca
-	github.com/tidwall/sjson v1.1.1
-	github.com/valyala/fasthttp v1.13.1
+	github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c
+	github.com/valyala/fasthttp v1.14.0
 	github.com/valyala/quicktemplate v1.5.0
 	github.com/valyala/quicktemplate v1.5.0
-	go.mongodb.org/mongo-driver v1.3.3
 )
 )

+ 4 - 82
frameworks/Go/fasthttp/src/go.sum

@@ -1,4 +1,3 @@
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
 github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
 github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
 github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
@@ -9,39 +8,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
-github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
-github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
-github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
-github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
-github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
-github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
-github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
-github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
-github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
-github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
-github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
-github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
-github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
-github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
-github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
-github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
-github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
-github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
-github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
-github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
-github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
-github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
-github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
 github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
-github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
 github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
 github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
 github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
 github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
 github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
@@ -84,11 +53,6 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f
 github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jackc/puddle v1.1.0 h1:musOWczZC/rSbqut475Vfcczg7jJsdUQf0D6oKPLgNU=
 github.com/jackc/puddle v1.1.0 h1:musOWczZC/rSbqut475Vfcczg7jJsdUQf0D6oKPLgNU=
 github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
-github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
-github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
-github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
-github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
 github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
 github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -104,39 +68,26 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
 github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
-github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
-github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
-github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
 github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
-github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
-github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
 github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
 github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
 github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
-github.com/savsgio/gotils v0.0.0-20200413113635-8c468ce75cca h1:Qe7Mtuhjkk38HVpRtvWdziZJcwG3Qup1mfyvyOrcnyM=
-github.com/savsgio/gotils v0.0.0-20200413113635-8c468ce75cca/go.mod h1:TWNAOTaVzGOXq8RbEvHnhzA/A2sLZzgn0m6URjnukY8=
+github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c h1:KKqhycXW1WVNkX7r4ekTV2gFkbhdyihlWD8c0/FiWmk=
+github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c/go.mod h1:TWNAOTaVzGOXq8RbEvHnhzA/A2sLZzgn0m6URjnukY8=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
-github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@@ -145,41 +96,23 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
-github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
-github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
-github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
-github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
-github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tidwall/sjson v1.1.1 h1:7h1vk049Jnd5EH9NyzNiEuwYW4b5qgreBbqRC19AS3U=
-github.com/tidwall/sjson v1.1.1/go.mod h1:yvVuSnpEQv5cYIrO+AT6kw4QVfd5SDZoGIS7/5+fZFs=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E=
 github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E=
-github.com/valyala/fasthttp v1.13.1 h1:Z7kVhKP9NZz+tCSY7AVhCMPPAk7b+e5fq0l/BfdTlFc=
-github.com/valyala/fasthttp v1.13.1/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
+github.com/valyala/fasthttp v1.14.0 h1:67bfuW9azCMwW/Jlq/C+VeihNpAuJMWkYPBig1gdi3A=
+github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
 github.com/valyala/quicktemplate v1.5.0 h1:2CUbkvZbxZ9m51wp5a2vzrbnv38Iocp0bMJomSmHyg0=
 github.com/valyala/quicktemplate v1.5.0 h1:2CUbkvZbxZ9m51wp5a2vzrbnv38Iocp0bMJomSmHyg0=
 github.com/valyala/quicktemplate v1.5.0/go.mod h1:v7yYWpBEiutDyNfVaph6oC/yKwejzVyTX/2cwwHxyok=
 github.com/valyala/quicktemplate v1.5.0/go.mod h1:v7yYWpBEiutDyNfVaph6oC/yKwejzVyTX/2cwwHxyok=
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
 github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
 github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
-go.mongodb.org/mongo-driver v1.3.3 h1:9kX7WY6sU/5qBuhm5mdnNWdqaDAQKB2qSZOd5wMEPGQ=
-go.mongodb.org/mongo-driver v1.3.3/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -188,18 +121,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -207,12 +135,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -221,7 +144,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

+ 45 - 0
frameworks/Go/fasthttp/src/handlers/db.go

@@ -0,0 +1,45 @@
+package handlers
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/jackc/pgx/v4/pgxpool"
+)
+
+const (
+	dbHost  = "tfb-database"
+	dbPort  = 5432
+	dbUser  = "benchmarkdbuser"
+	dbPaswd = "benchmarkdbpass"
+	dbName  = "hello_world"
+
+	worldSelectSQL   = "SELECT id, randomNumber FROM World WHERE id = $1"
+	worldUpdateSQL   = "UPDATE World SET randomNumber = $1 WHERE id = $2"
+	fortuneSelectSQL = "SELECT id, message FROM Fortune"
+)
+
+var db *pgxpool.Pool
+
+func InitDB(maxConn int) error {
+	pgx, err := newPGX(maxConn)
+	if err != nil {
+		return err
+	}
+
+	db = pgx
+
+	return nil
+}
+
+func CloseDB() {
+	db.Close()
+}
+
+func newPGX(maxConn int) (*pgxpool.Pool, error) {
+	dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s pool_max_conns=%d",
+		dbHost, dbPort, dbUser, dbPaswd, dbName, maxConn,
+	)
+
+	return pgxpool.Connect(context.Background(), dsn)
+}

+ 86 - 91
frameworks/Go/fasthttp/src/handlers/handlers.go

@@ -4,134 +4,129 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"sort"
 	"sort"
 
 
-	"fasthttp/src/storage"
 	"fasthttp/src/templates"
 	"fasthttp/src/templates"
 
 
+	pgx "github.com/jackc/pgx/v4"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp"
 )
 )
 
 
-const helloWorldStr = "Hello, World!"
+const (
+	helloWorldStr = "Hello, World!"
 
 
-func queriesParam(ctx *fasthttp.RequestCtx) int {
-	n := ctx.QueryArgs().GetUintOrZero("queries")
-	if n < 1 {
-		n = 1
-	} else if n > 500 {
-		n = 500
-	}
-
-	return n
-}
+	contentTypeJSON = "application/json"
+	contentTypeHTML = "text/html; charset=utf-8"
+)
 
 
-// JSONHandler . Test 1: JSON serialization
-func JSONHandler(ctx *fasthttp.RequestCtx) {
-	message := AcquireMessage()
+// JSON . Test 1: JSON serialization.
+func JSON(ctx *fasthttp.RequestCtx) {
+	message := acquireMessage()
 	message.Message = helloWorldStr
 	message.Message = helloWorldStr
 	data, _ := json.Marshal(message)
 	data, _ := json.Marshal(message)
 
 
-	ctx.SetContentType("application/json")
-	ctx.Write(data)
+	ctx.Response.Header.SetContentType(contentTypeJSON)
+	ctx.Response.SetBody(data)
 
 
-	ReleaseMessage(message)
+	releaseMessage(message)
 }
 }
 
 
-// DBHandler . Test 2: Single database query
-func DBHandler(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		world := storage.AcquireWorld()
-		db.GetOneRandomWorld(world)
-		data, _ := json.Marshal(world)
+// DB . Test 2: Single database query.
+func DB(ctx *fasthttp.RequestCtx) {
+	w := acquireWorld()
+	id := randomWorldNum()
 
 
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
+	db.QueryRow(ctx, worldSelectSQL, id).Scan(&w.ID, &w.RandomNumber) // nolint:errcheck
+	data, _ := json.Marshal(w)
 
 
-		storage.ReleaseWorld(world)
-	}
-}
-
-// QueriesHandler . Test 3: Multiple database queries
-func QueriesHandler(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
+	ctx.Response.Header.SetContentType(contentTypeJSON)
+	ctx.Response.SetBody(data)
 
 
-		for i := 0; i < queries; i++ {
-			db.GetOneRandomWorld(&worlds[i])
-		}
+	releaseWorld(w)
+}
 
 
-		data, _ := json.Marshal(worlds)
+// Queries . Test 3: Multiple database queries.
+func Queries(ctx *fasthttp.RequestCtx) {
+	queries := queriesParam(ctx)
+	worlds := acquireWorlds()
+	worlds.W = worlds.W[:queries]
 
 
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
+	for i := range worlds.W {
+		w := &worlds.W[i]
+		id := randomWorldNum()
 
 
-		storage.ReleaseWorlds(worlds)
+		db.QueryRow(ctx, worldSelectSQL, id).Scan(&w.ID, &w.RandomNumber) // nolint:errcheck
 	}
 	}
-}
 
 
-// FortuneHandler . Test 4: Fortunes
-func FortuneHandler(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		fortunes, _ := db.GetFortunes()
-		newFortune := templates.AcquireFortune()
-		newFortune.Message = "Additional fortune added at request time."
-		fortunes = append(fortunes, *newFortune)
+	data, _ := json.Marshal(worlds.W)
 
 
-		sort.Slice(fortunes, func(i, j int) bool {
-			return fortunes[i].Message < fortunes[j].Message
-		})
+	ctx.Response.Header.SetContentType(contentTypeJSON)
+	ctx.Response.SetBody(data)
 
 
-		ctx.SetContentType("text/html; charset=utf-8")
+	releaseWorlds(worlds)
+}
 
 
-		templates.FortuneTemplate.Execute(ctx, fortunes)
+// FortuneQuick . Test 4: Fortunes.
+func FortuneQuick(ctx *fasthttp.RequestCtx) {
+	fortune := templates.AcquireFortune()
+	fortunes := templates.AcquireFortunes()
 
 
-		templates.ReleaseFortune(newFortune)
-		templates.ReleaseFortunes(fortunes)
+	rows, _ := db.Query(ctx, fortuneSelectSQL)
+	for rows.Next() {
+		rows.Scan(&fortune.ID, &fortune.Message) // nolint:errcheck
+		fortunes.F = append(fortunes.F, *fortune)
 	}
 	}
-}
 
 
-// FortuneQuickHandler . Test 4: Fortunes
-func FortuneQuickHandler(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		fortunes, _ := db.GetFortunes()
-		newFortune := templates.AcquireFortune()
-		newFortune.Message = "Additional fortune added at request time."
-		fortunes = append(fortunes, *newFortune)
+	fortune.ID = 0
+	fortune.Message = "Additional fortune added at request time."
+	fortunes.F = append(fortunes.F, *fortune)
 
 
-		sort.Slice(fortunes, func(i, j int) bool {
-			return fortunes[i].Message < fortunes[j].Message
-		})
+	sort.Slice(fortunes.F, func(i, j int) bool {
+		return fortunes.F[i].Message < fortunes.F[j].Message
+	})
 
 
-		ctx.SetContentType("text/html; charset=utf-8")
-		templates.WriteFortunePage(ctx, fortunes)
+	ctx.Response.Header.SetContentType(contentTypeHTML)
+	templates.WriteFortunePage(ctx, fortunes.F)
 
 
-		templates.ReleaseFortune(newFortune)
-		templates.ReleaseFortunes(fortunes)
-	}
+	templates.ReleaseFortune(fortune)
+	templates.ReleaseFortunes(fortunes)
 }
 }
 
 
-// UpdateHandler . Test 5: Database updates
-func UpdateHandler(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
+// Update . Test 5: Database updates.
+func Update(ctx *fasthttp.RequestCtx) {
+	queries := queriesParam(ctx)
+	worlds := acquireWorlds()
+	worlds.W = worlds.W[:queries]
 
 
-		for i := 0; i < queries; i++ {
-			w := &worlds[i]
-			db.GetOneRandomWorld(w)
-			w.RandomNumber = int32(storage.RandomWorldNum())
-		}
+	for i := range worlds.W {
+		w := &worlds.W[i]
+		id := randomWorldNum()
+
+		db.QueryRow(ctx, worldSelectSQL, id).Scan(&w.ID, &w.RandomNumber) // nolint:errcheck
+		w.RandomNumber = int32(randomWorldNum())
+	}
 
 
-		db.UpdateWorlds(worlds)
-		data, _ := json.Marshal(worlds)
+	// against deadlocks
+	sort.Slice(worlds.W, func(i, j int) bool {
+		return worlds.W[i].ID < worlds.W[j].ID
+	})
 
 
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
+	batch := &pgx.Batch{}
 
 
-		storage.ReleaseWorlds(worlds)
+	for i := range worlds.W {
+		w := &worlds.W[i]
+		batch.Queue(worldUpdateSQL, w.RandomNumber, w.ID)
 	}
 	}
+
+	db.SendBatch(ctx, batch).Close()
+
+	data, _ := json.Marshal(worlds.W)
+
+	ctx.Response.Header.SetContentType(contentTypeJSON)
+	ctx.Response.SetBody(data)
+
+	releaseWorlds(worlds)
 }
 }
 
 
-// PlaintextHandler . Test 6: Plaintext
-func PlaintextHandler(ctx *fasthttp.RequestCtx) {
-	ctx.WriteString(helloWorldStr)
+// Plaintext . Test 6: Plaintext.
+func Plaintext(ctx *fasthttp.RequestCtx) {
+	ctx.Response.SetBodyString(helloWorldStr)
 }
 }

+ 0 - 74
frameworks/Go/fasthttp/src/handlers/handlers_easyjson.go

@@ -1,74 +0,0 @@
-package handlers
-
-import (
-	"fasthttp/src/storage"
-
-	"github.com/valyala/fasthttp"
-)
-
-// JSONHandlerEasyJSON . Test 1: JSON serialization
-func JSONHandlerEasyJSON(ctx *fasthttp.RequestCtx) {
-	message := AcquireMessage()
-	message.Message = helloWorldStr
-	messageBytes, _ := message.MarshalJSON()
-
-	ctx.SetContentType("application/json")
-	ctx.Write(messageBytes)
-
-	ReleaseMessage(message)
-}
-
-// DBHandlerEasyJSON . Test 2: Single database query
-func DBHandlerEasyJSON(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		world := storage.AcquireWorld()
-		db.GetOneRandomWorld(world)
-		worldBytes, _ := world.MarshalJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(worldBytes)
-
-		storage.ReleaseWorld(world)
-	}
-}
-
-// QueriesHandlerEasyJSON . Test 3: Multiple database queries
-func QueriesHandlerEasyJSON(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
-
-		for i := 0; i < queries; i++ {
-			db.GetOneRandomWorld(&worlds[i])
-		}
-
-		worldsBytes, _ := worlds.MarshalJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(worldsBytes)
-
-		storage.ReleaseWorlds(worlds)
-	}
-}
-
-// UpdateHandlerEasyJSON . Test 5: Database updates
-func UpdateHandlerEasyJSON(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
-
-		for i := 0; i < queries; i++ {
-			w := &worlds[i]
-			db.GetOneRandomWorld(w)
-			w.RandomNumber = int32(storage.RandomWorldNum())
-		}
-
-		db.UpdateWorlds(worlds)
-		worldsBytes, _ := worlds.MarshalJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(worldsBytes)
-
-		storage.ReleaseWorlds(worlds)
-	}
-}

+ 0 - 74
frameworks/Go/fasthttp/src/handlers/handlers_sjson.go

@@ -1,74 +0,0 @@
-package handlers
-
-import (
-	"fasthttp/src/storage"
-
-	"github.com/valyala/fasthttp"
-)
-
-// JSONHandlerSJson . Test 1: JSON serialization
-func JSONHandlerSJson(ctx *fasthttp.RequestCtx) {
-	message := AcquireMessage()
-	message.Message = helloWorldStr
-	data, _ := message.MarshalSJSON()
-
-	ctx.SetContentType("application/json")
-	ctx.Write(data)
-
-	ReleaseMessage(message)
-}
-
-// DBHandlerSJson . Test 2: Single database query
-func DBHandlerSJson(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		world := storage.AcquireWorld()
-		db.GetOneRandomWorld(world)
-		data, _ := world.MarshalSJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
-
-		storage.ReleaseWorld(world)
-	}
-}
-
-// QueriesHandlerSJson . Test 3: Multiple database queries
-func QueriesHandlerSJson(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
-
-		for i := 0; i < queries; i++ {
-			db.GetOneRandomWorld(&worlds[i])
-		}
-
-		data, _ := worlds.MarshalSJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
-
-		storage.ReleaseWorlds(worlds)
-	}
-}
-
-// UpdateHandlerSJson . Test 5: Database updates
-func UpdateHandlerSJson(db storage.DB) fasthttp.RequestHandler {
-	return func(ctx *fasthttp.RequestCtx) {
-		queries := queriesParam(ctx)
-		worlds := storage.AcquireWorlds()[:queries]
-
-		for i := 0; i < queries; i++ {
-			w := &worlds[i]
-			db.GetOneRandomWorld(w)
-			w.RandomNumber = int32(storage.RandomWorldNum())
-		}
-
-		db.UpdateWorlds(worlds)
-		data, _ := worlds.MarshalSJSON()
-
-		ctx.SetContentType("application/json")
-		ctx.Write(data)
-
-		storage.ReleaseWorlds(worlds)
-	}
-}

+ 5 - 27
frameworks/Go/fasthttp/src/handlers/message.go

@@ -2,41 +2,19 @@ package handlers
 
 
 import (
 import (
 	"sync"
 	"sync"
-
-	"github.com/tidwall/sjson"
 )
 )
 
 
-// Message struct
-type Message struct {
-	Message string `json:"message"`
-}
-
-var messageJSONStr = []byte(`{"message": ""}`)
-
-// MessagePool ...
-var MessagePool = sync.Pool{
+var messagePool = &sync.Pool{
 	New: func() interface{} {
 	New: func() interface{} {
 		return new(Message)
 		return new(Message)
 	},
 	},
 }
 }
 
 
-// AcquireMessage returns new message from pool
-func AcquireMessage() *Message {
-	return MessagePool.Get().(*Message)
+func acquireMessage() *Message {
+	return messagePool.Get().(*Message)
 }
 }
 
 
-// ReleaseMessage resets the message and return it to the pool
-func ReleaseMessage(m *Message) {
+func releaseMessage(m *Message) {
 	m.Message = ""
 	m.Message = ""
-	MessagePool.Put(m)
-}
-
-// IsNil returns true if the object is nil
-func (m *Message) IsNil() bool {
-	return m == nil
-}
-
-// MarshalSJSON marshals the object as json
-func (m Message) MarshalSJSON() ([]byte, error) {
-	return sjson.SetBytesOptions(messageJSONStr, "message", m.Message, &sjson.Options{Optimistic: true})
+	messagePool.Put(m)
 }
 }

+ 0 - 85
frameworks/Go/fasthttp/src/handlers/message_easyjson.go

@@ -1,85 +0,0 @@
-// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
-
-package handlers
-
-import (
-	json "encoding/json"
-	easyjson "github.com/mailru/easyjson"
-	jlexer "github.com/mailru/easyjson/jlexer"
-	jwriter "github.com/mailru/easyjson/jwriter"
-)
-
-// suppress unused package warning
-var (
-	_ *json.RawMessage
-	_ *jlexer.Lexer
-	_ *jwriter.Writer
-	_ easyjson.Marshaler
-)
-
-func easyjson4086215fDecodeFasthttpSrcHandlers(in *jlexer.Lexer, out *Message) {
-	isTopLevel := in.IsStart()
-	if in.IsNull() {
-		if isTopLevel {
-			in.Consumed()
-		}
-		in.Skip()
-		return
-	}
-	in.Delim('{')
-	for !in.IsDelim('}') {
-		key := in.UnsafeString()
-		in.WantColon()
-		if in.IsNull() {
-			in.Skip()
-			in.WantComma()
-			continue
-		}
-		switch key {
-		case "message":
-			out.Message = string(in.String())
-		default:
-			in.SkipRecursive()
-		}
-		in.WantComma()
-	}
-	in.Delim('}')
-	if isTopLevel {
-		in.Consumed()
-	}
-}
-func easyjson4086215fEncodeFasthttpSrcHandlers(out *jwriter.Writer, in Message) {
-	out.RawByte('{')
-	first := true
-	_ = first
-	{
-		const prefix string = ",\"message\":"
-		out.RawString(prefix[1:])
-		out.String(string(in.Message))
-	}
-	out.RawByte('}')
-}
-
-// MarshalJSON supports json.Marshaler interface
-func (v Message) MarshalJSON() ([]byte, error) {
-	w := jwriter.Writer{}
-	easyjson4086215fEncodeFasthttpSrcHandlers(&w, v)
-	return w.Buffer.BuildBytes(), w.Error
-}
-
-// MarshalEasyJSON supports easyjson.Marshaler interface
-func (v Message) MarshalEasyJSON(w *jwriter.Writer) {
-	easyjson4086215fEncodeFasthttpSrcHandlers(w, v)
-}
-
-// UnmarshalJSON supports json.Unmarshaler interface
-func (v *Message) UnmarshalJSON(data []byte) error {
-	r := jlexer.Lexer{Data: data}
-	easyjson4086215fDecodeFasthttpSrcHandlers(&r, v)
-	return r.Error()
-}
-
-// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
-func (v *Message) UnmarshalEasyJSON(l *jlexer.Lexer) {
-	easyjson4086215fDecodeFasthttpSrcHandlers(l, v)
-}

+ 14 - 0
frameworks/Go/fasthttp/src/handlers/types.go

@@ -0,0 +1,14 @@
+package handlers
+
+type Message struct {
+	Message string `json:"message"`
+}
+
+type World struct {
+	ID           int32 `json:"id"`
+	RandomNumber int32 `json:"randomnumber"`
+}
+
+type Worlds struct {
+	W []World
+}

+ 24 - 0
frameworks/Go/fasthttp/src/handlers/utils.go

@@ -0,0 +1,24 @@
+package handlers
+
+import (
+	"math/rand"
+
+	"github.com/valyala/fasthttp"
+)
+
+const worldsCount = 10000
+
+func queriesParam(ctx *fasthttp.RequestCtx) int {
+	n := ctx.QueryArgs().GetUintOrZero("queries")
+	if n < 1 {
+		n = 1
+	} else if n > 500 {
+		n = 500
+	}
+
+	return n
+}
+
+func randomWorldNum() int {
+	return rand.Intn(worldsCount) + 1
+}

+ 38 - 0
frameworks/Go/fasthttp/src/handlers/world.go

@@ -0,0 +1,38 @@
+package handlers
+
+import (
+	"sync"
+)
+
+var worldPool = &sync.Pool{
+	New: func() interface{} {
+		return new(World)
+	},
+}
+
+var worldsPool = &sync.Pool{
+	New: func() interface{} {
+		return &Worlds{
+			W: make([]World, 0, 512),
+		}
+	},
+}
+
+func acquireWorld() *World {
+	return worldPool.Get().(*World)
+}
+
+func releaseWorld(w *World) {
+	w.ID = 0
+	w.RandomNumber = 0
+	worldPool.Put(w)
+}
+
+func acquireWorlds() *Worlds {
+	return worldsPool.Get().(*Worlds)
+}
+
+func releaseWorlds(w *Worlds) {
+	w.W = w.W[:0]
+	worldsPool.Put(w)
+}

+ 19 - 65
frameworks/Go/fasthttp/src/main.go

@@ -2,29 +2,21 @@ package main
 
 
 import (
 import (
 	"flag"
 	"flag"
-	"fmt"
-	"log"
 	"runtime"
 	"runtime"
 
 
 	"fasthttp/src/handlers"
 	"fasthttp/src/handlers"
-	"fasthttp/src/storage"
 
 
 	"github.com/savsgio/gotils"
 	"github.com/savsgio/gotils"
 	"github.com/valyala/fasthttp"
 	"github.com/valyala/fasthttp"
 	fastprefork "github.com/valyala/fasthttp/prefork"
 	fastprefork "github.com/valyala/fasthttp/prefork"
 )
 )
 
 
-var bindHost, jsonEncoder, dbDriver, dbConnectionString string
-var prefork, useQuickTemplate bool
+var bindHost string
+var prefork bool
 
 
 func init() {
 func init() {
-	// init flags
 	flag.StringVar(&bindHost, "bind", ":8080", "set bind host")
 	flag.StringVar(&bindHost, "bind", ":8080", "set bind host")
 	flag.BoolVar(&prefork, "prefork", false, "use prefork")
 	flag.BoolVar(&prefork, "prefork", false, "use prefork")
-	flag.StringVar(&jsonEncoder, "json_encoder", "none", "json encoder: none or easyjson or sjson")
-	flag.StringVar(&dbDriver, "db", "none", "db connection driver [values: none or pgx or mongo]")
-	flag.StringVar(&dbConnectionString, "db_connection_string", "", "db connection string")
-	flag.BoolVar(&useQuickTemplate, "quicktemplate", false, "use quicktemplate")
 
 
 	flag.Parse()
 	flag.Parse()
 }
 }
@@ -44,81 +36,43 @@ func main() {
 		maxConn = numCPU()
 		maxConn = numCPU()
 	}
 	}
 
 
-	if dbConnectionString == "" {
-		dbConnectionString = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s pool_max_conns=%d", "tfb-database", 5432, "benchmarkdbuser", "benchmarkdbpass", "hello_world", maxConn)
-	}
-
-	// init database with appropriate driver
-	db, err := storage.InitDB(dbDriver, dbConnectionString, maxConn)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	if db != nil {
-		defer db.Close()
-	}
-
-	// init json encoders
-	var jsonHandler, dbHandler, queriesHandler, updateHandler, fortuneHandler fasthttp.RequestHandler
-
-	if useQuickTemplate {
-		fortuneHandler = handlers.FortuneQuickHandler(db)
-	} else {
-		fortuneHandler = handlers.FortuneHandler(db)
-	}
-
-	switch jsonEncoder {
-	case "easyjson":
-		jsonHandler = handlers.JSONHandlerEasyJSON
-		dbHandler = handlers.DBHandlerEasyJSON(db)
-		queriesHandler = handlers.QueriesHandlerEasyJSON(db)
-		updateHandler = handlers.UpdateHandlerEasyJSON(db)
-	case "sjson":
-		jsonHandler = handlers.JSONHandlerSJson
-		dbHandler = handlers.DBHandlerSJson(db)
-		queriesHandler = handlers.QueriesHandlerSJson(db)
-		updateHandler = handlers.UpdateHandlerSJson(db)
-	default:
-		jsonHandler = handlers.JSONHandler
-		dbHandler = handlers.DBHandler(db)
-		queriesHandler = handlers.QueriesHandler(db)
-		updateHandler = handlers.UpdateHandler(db)
+	// init database
+	if err := handlers.InitDB(maxConn); err != nil {
+		panic(err)
 	}
 	}
+	defer handlers.CloseDB()
 
 
 	handler := func(ctx *fasthttp.RequestCtx) {
 	handler := func(ctx *fasthttp.RequestCtx) {
 		switch gotils.B2S(ctx.Path()) {
 		switch gotils.B2S(ctx.Path()) {
 		case "/plaintext":
 		case "/plaintext":
-			handlers.PlaintextHandler(ctx)
+			handlers.Plaintext(ctx)
 		case "/json":
 		case "/json":
-			jsonHandler(ctx)
+			handlers.JSON(ctx)
 		case "/db":
 		case "/db":
-			dbHandler(ctx)
+			handlers.DB(ctx)
 		case "/queries":
 		case "/queries":
-			queriesHandler(ctx)
+			handlers.Queries(ctx)
 		case "/fortune":
 		case "/fortune":
-			fortuneHandler(ctx)
+			handlers.FortuneQuick(ctx)
 		case "/update":
 		case "/update":
-			updateHandler(ctx)
+			handlers.Update(ctx)
 		default:
 		default:
 			ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound), fasthttp.StatusNotFound)
 			ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound), fasthttp.StatusNotFound)
 		}
 		}
 	}
 	}
 
 
+	// init fasthttp server
 	server := &fasthttp.Server{
 	server := &fasthttp.Server{
-		Handler: handler,
 		Name:    "Go",
 		Name:    "Go",
+		Handler: handler,
 	}
 	}
 
 
+	listenAndServe := server.ListenAndServe
 	if prefork {
 	if prefork {
-		preforkServer := fastprefork.New(server)
-
-		if err := preforkServer.ListenAndServe(bindHost); err != nil {
-			panic(err)
-		}
+		listenAndServe = fastprefork.New(server).ListenAndServe
+	}
 
 
-	} else {
-		if err := server.ListenAndServe(bindHost); err != nil {
-			panic(err)
-		}
+	if err := listenAndServe(bindHost); err != nil {
+		panic(err)
 	}
 	}
 }
 }

+ 0 - 43
frameworks/Go/fasthttp/src/storage/db.go

@@ -1,43 +0,0 @@
-package storage
-
-import (
-	"errors"
-	"math/rand"
-
-	"fasthttp/src/templates"
-)
-
-const (
-	worldsCount = 10000
-
-	worldSelectSQL   = "SELECT id, randomNumber FROM World WHERE id = $1"
-	worldUpdateSQL   = "UPDATE World SET randomNumber = $1 WHERE id = $2"
-	fortuneSelectSQL = "SELECT id, message FROM Fortune"
-)
-
-// DB is interface for
-type DB interface {
-	// GetOneRandomWorld() (World, error)
-	GetOneRandomWorld(*World) error
-	UpdateWorlds(Worlds) error
-	GetFortunes() (templates.Fortunes, error)
-	Close()
-}
-
-func RandomWorldNum() int {
-	return rand.Intn(worldsCount) + 1
-}
-
-// InitDB with appropriate driver
-func InitDB(dbDriver, dbConnectionString string, maxConnectionCount int) (DB, error) {
-	switch dbDriver {
-	case "pgx":
-		return NewPgxDB(dbConnectionString)
-	case "mongo":
-		return NewMongoDB(dbConnectionString, maxConnectionCount)
-	case "none":
-		return nil, nil
-	}
-
-	return nil, errors.New("can not recognize DB driver type")
-}

+ 0 - 108
frameworks/Go/fasthttp/src/storage/mongo.go

@@ -1,108 +0,0 @@
-package storage
-
-import (
-	"context"
-
-	"fasthttp/src/templates"
-
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
-	"go.mongodb.org/mongo-driver/mongo/readpref"
-)
-
-// Mongo struct
-type Mongo struct {
-	db       *mongo.Client
-	database *mongo.Database
-	// mongodb collections
-	worlds   *mongo.Collection
-	fortunes *mongo.Collection
-}
-
-// NewMongoDB creates new connection to postgres db with official mongo driver
-func NewMongoDB(dbConnectionString string, maxConnectionsInPool int) (DB, error) {
-	m := new(Mongo)
-
-	if err := m.Connect(dbConnectionString, maxConnectionsInPool); err != nil {
-		return nil, err
-	}
-
-	return m, nil
-}
-
-// Connect create connection and ping db
-func (m *Mongo) Connect(dbConnectionString string, maxConnectionsInPool int) error {
-	var err error
-
-	opts := options.Client()
-	opts.SetMaxPoolSize(uint64(maxConnectionsInPool))
-
-	m.db, err = mongo.Connect(context.Background(), opts.ApplyURI(dbConnectionString))
-	if err != nil {
-		return err
-	}
-
-	err = m.db.Ping(context.Background(), readpref.Primary())
-	if err != nil {
-		return err
-	}
-
-	m.database = m.db.Database("hello_world")
-	m.worlds = m.database.Collection("world")
-	m.fortunes = m.database.Collection("fortune")
-
-	return nil
-}
-
-// Close connect to db
-func (m *Mongo) Close() {
-	if err := m.db.Disconnect(context.Background()); err != nil {
-		panic(err)
-	}
-}
-
-// GetOneRandomWorld return one random World struct
-func (m *Mongo) GetOneRandomWorld(w *World) error {
-	id := RandomWorldNum()
-	filter := bson.M{"_id": id}
-
-	return m.worlds.FindOne(context.Background(), filter).Decode(w)
-}
-
-// UpdateWorlds updates some number of worlds entries, passed as arg
-func (m *Mongo) UpdateWorlds(worlds Worlds) error {
-	var operations []mongo.WriteModel
-
-	for _, w := range worlds {
-		operation := mongo.NewUpdateOneModel()
-		operation.SetFilter(bson.M{"_id": w.ID})
-		operation.SetUpdate(bson.M{"$set": bson.M{"randomNumber": w.RandomNumber}})
-		operations = append(operations, operation)
-	}
-
-	_, err := m.worlds.BulkWrite(context.Background(), operations)
-
-	return err
-}
-
-// GetFortunes selects all fortunes from table
-func (m *Mongo) GetFortunes() (templates.Fortunes, error) {
-	cur, err := m.fortunes.Find(context.Background(), bson.M{})
-	if err != nil {
-		return nil, err
-	}
-	defer cur.Close(context.Background())
-
-	fortunes := templates.AcquireFortunes()
-	fortune := templates.AcquireFortune()
-
-	for cur.Next(context.Background()) {
-		cur.Decode(fortune)
-		fortunes = append(fortunes, *fortune)
-	}
-
-	templates.ReleaseFortune(fortune)
-
-	return fortunes, cur.Err()
-}

+ 0 - 86
frameworks/Go/fasthttp/src/storage/pgx.go

@@ -1,86 +0,0 @@
-package storage
-
-import (
-	"context"
-	"sort"
-
-	"fasthttp/src/templates"
-
-	pgx "github.com/jackc/pgx/v4"
-	"github.com/jackc/pgx/v4/pgxpool"
-)
-
-// PGX struct
-type PGX struct {
-	db *pgxpool.Pool
-}
-
-// NewPgxDB creates new connection to postgres db with pgx driver
-func NewPgxDB(dbConnectionString string) (DB, error) {
-	psql := new(PGX)
-	if err := psql.Connect(dbConnectionString); err != nil {
-		return nil, err
-	}
-
-	return psql, nil
-}
-
-// Connect create connection and ping db
-func (psql *PGX) Connect(dbConnectionString string) error {
-	var err error
-
-	if psql.db, err = pgxpool.Connect(context.Background(), dbConnectionString); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// Close connect to db
-func (psql *PGX) Close() {
-	psql.db.Close()
-}
-
-// GetOneRandomWorld return one random World struct
-func (psql *PGX) GetOneRandomWorld(w *World) error {
-	id := RandomWorldNum()
-
-	return psql.db.QueryRow(context.Background(), worldSelectSQL, id).Scan(&w.ID, &w.RandomNumber)
-}
-
-// UpdateWorlds updates some number of worlds entries, passed as arg
-func (psql *PGX) UpdateWorlds(worlds Worlds) error {
-	// against deadlocks
-	sort.Slice(worlds, func(i, j int) bool {
-		return worlds[i].ID < worlds[j].ID
-	})
-
-	batch := pgx.Batch{}
-
-	for _, w := range worlds {
-		batch.Queue(worldUpdateSQL, w.RandomNumber, w.ID)
-	}
-
-	return psql.db.SendBatch(context.Background(), &batch).Close()
-}
-
-// GetFortunes selects all fortunes from table
-func (psql *PGX) GetFortunes() (templates.Fortunes, error) {
-	rows, err := psql.db.Query(context.Background(), fortuneSelectSQL)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-
-	fortunes := templates.AcquireFortunes()
-	fortune := templates.AcquireFortune()
-
-	for rows.Next() {
-		rows.Scan(&fortune.ID, &fortune.Message)
-		fortunes = append(fortunes, *fortune)
-	}
-
-	templates.ReleaseFortune(fortune)
-
-	return fortunes, nil
-}

+ 0 - 85
frameworks/Go/fasthttp/src/storage/world.go

@@ -1,85 +0,0 @@
-package storage
-
-import (
-	"sync"
-
-	"github.com/tidwall/sjson"
-)
-
-var worldJSONStr = []byte(`{"id": 0, "randomNumber": 0}`)
-
-//easyjson:json
-type World struct {
-	ID           int32 `json:"id"`
-	RandomNumber int32 `json:"randomnumber"`
-}
-
-// WorldPool ...
-var WorldPool = sync.Pool{
-	New: func() interface{} {
-		return new(World)
-	},
-}
-
-// AcquireWorld returns new world from pool
-func AcquireWorld() *World {
-	return WorldPool.Get().(*World)
-}
-
-// ReleaseWorld resets the world and return it to the pool
-func ReleaseWorld(w *World) {
-	w.ID = 0
-	w.RandomNumber = 0
-	WorldPool.Put(w)
-}
-
-// IsNil returns true if the object is nil
-func (w *World) IsNil() bool {
-	return w == nil
-}
-
-// MarshalSJSON marshals the object as json
-func (w World) MarshalSJSON() ([]byte, error) {
-	data, _ := sjson.SetBytesOptions(worldJSONStr, "id", w.ID, &sjson.Options{Optimistic: true})
-
-	return sjson.SetBytesOptions(
-		data, "randomNumber", w.RandomNumber, &sjson.Options{Optimistic: true, ReplaceInPlace: true},
-	)
-}
-
-//easyjson:json
-type Worlds []World
-
-// WorldsPool ...
-var WorldsPool = sync.Pool{
-	New: func() interface{} {
-		return make(Worlds, 0, 512)
-	},
-}
-
-// AcquireWorlds returns new worlds from pool
-func AcquireWorlds() Worlds {
-	return WorldsPool.Get().(Worlds)
-}
-
-// ReleaseWorlds resets the worlds and return it to the pool
-func ReleaseWorlds(w Worlds) {
-	w = w[:0]
-	WorldsPool.Put(w)
-}
-
-// IsNil returns true if the object is nil
-func (ws Worlds) IsNil() bool {
-	return ws == nil
-}
-
-// MarshalSJSON marshals the object as json
-func (ws Worlds) MarshalSJSON() ([]byte, error) {
-	jsonResult := []byte(`[]`)
-
-	for _, w := range ws {
-		jsonResult, _ = sjson.SetBytesOptions(jsonResult, "-1", w, &sjson.Options{Optimistic: true, ReplaceInPlace: true})
-	}
-
-	return jsonResult, nil
-}

+ 0 - 158
frameworks/Go/fasthttp/src/storage/world_easyjson.go

@@ -1,158 +0,0 @@
-// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
-
-package storage
-
-import (
-	json "encoding/json"
-	easyjson "github.com/mailru/easyjson"
-	jlexer "github.com/mailru/easyjson/jlexer"
-	jwriter "github.com/mailru/easyjson/jwriter"
-)
-
-// suppress unused package warning
-var (
-	_ *json.RawMessage
-	_ *jlexer.Lexer
-	_ *jwriter.Writer
-	_ easyjson.Marshaler
-)
-
-func easyjson4da0dabeDecodeFasthttpSrcStorage(in *jlexer.Lexer, out *Worlds) {
-	isTopLevel := in.IsStart()
-	if in.IsNull() {
-		in.Skip()
-		*out = nil
-	} else {
-		in.Delim('[')
-		if *out == nil {
-			if !in.IsDelim(']') {
-				*out = make(Worlds, 0, 8)
-			} else {
-				*out = Worlds{}
-			}
-		} else {
-			*out = (*out)[:0]
-		}
-		for !in.IsDelim(']') {
-			var v1 World
-			(v1).UnmarshalEasyJSON(in)
-			*out = append(*out, v1)
-			in.WantComma()
-		}
-		in.Delim(']')
-	}
-	if isTopLevel {
-		in.Consumed()
-	}
-}
-func easyjson4da0dabeEncodeFasthttpSrcStorage(out *jwriter.Writer, in Worlds) {
-	if in == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
-		out.RawString("null")
-	} else {
-		out.RawByte('[')
-		for v2, v3 := range in {
-			if v2 > 0 {
-				out.RawByte(',')
-			}
-			(v3).MarshalEasyJSON(out)
-		}
-		out.RawByte(']')
-	}
-}
-
-// MarshalJSON supports json.Marshaler interface
-func (v Worlds) MarshalJSON() ([]byte, error) {
-	w := jwriter.Writer{}
-	easyjson4da0dabeEncodeFasthttpSrcStorage(&w, v)
-	return w.Buffer.BuildBytes(), w.Error
-}
-
-// MarshalEasyJSON supports easyjson.Marshaler interface
-func (v Worlds) MarshalEasyJSON(w *jwriter.Writer) {
-	easyjson4da0dabeEncodeFasthttpSrcStorage(w, v)
-}
-
-// UnmarshalJSON supports json.Unmarshaler interface
-func (v *Worlds) UnmarshalJSON(data []byte) error {
-	r := jlexer.Lexer{Data: data}
-	easyjson4da0dabeDecodeFasthttpSrcStorage(&r, v)
-	return r.Error()
-}
-
-// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
-func (v *Worlds) UnmarshalEasyJSON(l *jlexer.Lexer) {
-	easyjson4da0dabeDecodeFasthttpSrcStorage(l, v)
-}
-func easyjson4da0dabeDecodeFasthttpSrcStorage1(in *jlexer.Lexer, out *World) {
-	isTopLevel := in.IsStart()
-	if in.IsNull() {
-		if isTopLevel {
-			in.Consumed()
-		}
-		in.Skip()
-		return
-	}
-	in.Delim('{')
-	for !in.IsDelim('}') {
-		key := in.UnsafeString()
-		in.WantColon()
-		if in.IsNull() {
-			in.Skip()
-			in.WantComma()
-			continue
-		}
-		switch key {
-		case "id":
-			out.ID = int32(in.Int32())
-		case "randomnumber":
-			out.RandomNumber = int32(in.Int32())
-		default:
-			in.SkipRecursive()
-		}
-		in.WantComma()
-	}
-	in.Delim('}')
-	if isTopLevel {
-		in.Consumed()
-	}
-}
-func easyjson4da0dabeEncodeFasthttpSrcStorage1(out *jwriter.Writer, in World) {
-	out.RawByte('{')
-	first := true
-	_ = first
-	{
-		const prefix string = ",\"id\":"
-		out.RawString(prefix[1:])
-		out.Int32(int32(in.ID))
-	}
-	{
-		const prefix string = ",\"randomnumber\":"
-		out.RawString(prefix)
-		out.Int32(int32(in.RandomNumber))
-	}
-	out.RawByte('}')
-}
-
-// MarshalJSON supports json.Marshaler interface
-func (v World) MarshalJSON() ([]byte, error) {
-	w := jwriter.Writer{}
-	easyjson4da0dabeEncodeFasthttpSrcStorage1(&w, v)
-	return w.Buffer.BuildBytes(), w.Error
-}
-
-// MarshalEasyJSON supports easyjson.Marshaler interface
-func (v World) MarshalEasyJSON(w *jwriter.Writer) {
-	easyjson4da0dabeEncodeFasthttpSrcStorage1(w, v)
-}
-
-// UnmarshalJSON supports json.Unmarshaler interface
-func (v *World) UnmarshalJSON(data []byte) error {
-	r := jlexer.Lexer{Data: data}
-	easyjson4da0dabeDecodeFasthttpSrcStorage1(&r, v)
-	return r.Error()
-}
-
-// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
-func (v *World) UnmarshalEasyJSON(l *jlexer.Lexer) {
-	easyjson4da0dabeDecodeFasthttpSrcStorage1(l, v)
-}

+ 19 - 57
frameworks/Go/fasthttp/src/templates/fortune.go

@@ -1,82 +1,44 @@
 package templates
 package templates
 
 
 import (
 import (
-	"html/template"
 	"sync"
 	"sync"
 )
 )
 
 
 //go:generate qtc
 //go:generate qtc
 
 
-const (
-	fortuneHTML = `<!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>`
-)
-
-var (
-	// FortuneTemplate ...
-	FortuneTemplate = template.Must(template.New("fortune.html").Parse(fortuneHTML))
-)
-
-// Fortune struct
-type Fortune struct {
-	ID      int    `json:"id,omitempty"`
-	Message string `json:"message,omitempty"`
+var fortunePool = &sync.Pool{
+	New: func() interface{} {
+		return new(Fortune)
+	},
 }
 }
 
 
-// FortunePool ...
-var FortunePool = &sync.Pool{
+var fortunesPool = &sync.Pool{
 	New: func() interface{} {
 	New: func() interface{} {
-		return new(Fortune)
+		return &Fortunes{
+			F: make([]Fortune, 0, 16),
+		}
 	},
 	},
 }
 }
 
 
-// AcquireFortune returns new message from pool
+// AcquireFortune returns new message from pool.
 func AcquireFortune() *Fortune {
 func AcquireFortune() *Fortune {
-	return FortunePool.Get().(*Fortune)
+	return fortunePool.Get().(*Fortune)
 }
 }
 
 
-// ReleaseFortune resets the message and return it to the pool
+// ReleaseFortune resets the message and return it to the pool.
 func ReleaseFortune(f *Fortune) {
 func ReleaseFortune(f *Fortune) {
 	f.ID = 0
 	f.ID = 0
 	f.Message = ""
 	f.Message = ""
-	FortunePool.Put(f)
-}
-
-// Fortunes ...
-type Fortunes []Fortune
-
-// FortunesPool ...
-var FortunesPool = sync.Pool{
-	New: func() interface{} {
-		return make(Fortunes, 0, 16)
-	},
+	fortunePool.Put(f)
 }
 }
 
 
-// AcquireFortunes returns new fortunes from pool
-func AcquireFortunes() Fortunes {
-	return FortunesPool.Get().(Fortunes)
+// AcquireFortunes returns new fortunes from pool.
+func AcquireFortunes() *Fortunes {
+	return fortunesPool.Get().(*Fortunes)
 }
 }
 
 
-// ReleaseFortunes resets the fortunes and return it to the pool
-func ReleaseFortunes(f Fortunes) {
-	f = f[:0]
-	FortunesPool.Put(f)
+// ReleaseFortunes resets the fortunes and return it to the pool.
+func ReleaseFortunes(f *Fortunes) {
+	f.F = f.F[:0]
+	fortunesPool.Put(f)
 }
 }

+ 1 - 1
frameworks/Go/fasthttp/src/templates/fortunes.qtpl

@@ -1,4 +1,4 @@
-{% func FortunePage(rows Fortunes) %}<!DOCTYPE html>
+{% func FortunePage(rows []Fortune) %}<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Fortunes</title>
 <title>Fortunes</title>

+ 3 - 3
frameworks/Go/fasthttp/src/templates/fortunes.qtpl.go

@@ -18,7 +18,7 @@ var (
 )
 )
 
 
 //line fortunes.qtpl:1
 //line fortunes.qtpl:1
-func StreamFortunePage(qw422016 *qt422016.Writer, rows Fortunes) {
+func StreamFortunePage(qw422016 *qt422016.Writer, rows []Fortune) {
 //line fortunes.qtpl:1
 //line fortunes.qtpl:1
 	qw422016.N().S(`<!DOCTYPE html>
 	qw422016.N().S(`<!DOCTYPE html>
 <html>
 <html>
@@ -55,7 +55,7 @@ func StreamFortunePage(qw422016 *qt422016.Writer, rows Fortunes) {
 }
 }
 
 
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15
-func WriteFortunePage(qq422016 qtio422016.Writer, rows Fortunes) {
+func WriteFortunePage(qq422016 qtio422016.Writer, rows []Fortune) {
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15
 	qw422016 := qt422016.AcquireWriter(qq422016)
 	qw422016 := qt422016.AcquireWriter(qq422016)
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15
@@ -66,7 +66,7 @@ func WriteFortunePage(qq422016 qtio422016.Writer, rows Fortunes) {
 }
 }
 
 
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15
-func FortunePage(rows Fortunes) string {
+func FortunePage(rows []Fortune) string {
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15
 	qb422016 := qt422016.AcquireByteBuffer()
 	qb422016 := qt422016.AcquireByteBuffer()
 //line fortunes.qtpl:15
 //line fortunes.qtpl:15

+ 10 - 0
frameworks/Go/fasthttp/src/templates/types.go

@@ -0,0 +1,10 @@
+package templates
+
+type Fortune struct {
+	ID      int    `json:"id,omitempty"`
+	Message string `json:"message,omitempty"`
+}
+
+type Fortunes struct {
+	F []Fortune
+}