Skip to content

Instantly share code, notes, and snippets.

@miry
Last active August 29, 2015 14:10
Show Gist options
  • Save miry/e3ec65c67c533c86842a to your computer and use it in GitHub Desktop.
Save miry/e3ec65c67c533c86842a to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net/http"
"github.com/HitFox/ad_server/app"
"github.com/HitFox/ad_server/handler/bulk"
"github.com/HitFox/ad_server/mid"
"runtime"
)
func main() {
fmt.Printf("Start %d processes\n", runtime.NumCPU())
runtime.GOMAXPROCS(runtime.NumCPU())
app := app.Setup()
http.HandleFunc("/api/bulk/v1/promotions", mid.Wrap(app, bulk.Handler))
fmt.Println("Bind server on port 8080")
er := http.ListenAndServe(":8080", nil)
if er != nil {
fmt.Println(er)
}
}
package mid
import (
"fmt"
"log"
"net/http"
"os"
uuid "github.com/nu7hatch/gouuid"
"github.com/HitFox/ad_server/app"
"github.com/garyburd/redigo/redis"
)
type CntFunc func(*Context) error
type Context struct {
App *app.App
Req *http.Request
Res http.ResponseWriter
BufRes *BufRes
Log *Log
LocRedis redis.Conn
RegRedis *redis.Conn
}
type BufRes struct {
buf *[]byte
}
func newBufRes() *BufRes {
buf := new([]byte)
*buf = make([]byte, 0)
return &BufRes{buf}
}
func (b *BufRes) Write(bytes []byte) (int, error) {
*b.buf = append(*b.buf, bytes...)
return len(bytes), nil
}
type Log struct {
uuid *uuid.UUID
info *log.Logger
error *log.Logger
}
func (l *Log) Info(msg ...interface{}) {
l.info.Print(msg...)
}
func (l *Log) Error(msg ...interface{}) {
l.error.Print(msg...)
}
func LogMid(mid CntFunc) CntFunc {
return func(ctx *Context) error {
u, err := uuid.NewV4()
if err != nil {
return err
}
ctx.Log = &Log{
uuid: u,
info: log.New(os.Stdout, fmt.Sprintf("%s: ", u), log.Ldate|log.Ltime),
error: log.New(os.Stderr, fmt.Sprintf("%s: ", u), log.Ldate|log.Ltime),
}
ctx.Log.Info(ctx.Req.RequestURI)
return mid(ctx)
}
}
func RedisMid(mid CntFunc) CntFunc {
return func(ctx *Context) error {
conn := ctx.App.Redis.Local.Get()
defer func() {
if err := conn.Close(); err != nil {
ctx.Log.Info(err)
}
}()
ctx.LocRedis = conn
return mid(ctx)
}
}
func ContTypeMid(mid CntFunc) CntFunc {
return func(ctx *Context) error {
ctx.Res.Header().Set("Content-Type", "application/json")
if err := mid(ctx); err != nil {
ctx.Res.WriteHeader(422)
ctx.Res.Write([]byte("{\"error\":\"" + err.Error() + "\"}"))
ctx.Log.Info("STATUS: 422")
return err
} else {
ctx.Res.Write(*ctx.BufRes.buf)
ctx.Log.Info("STATUS: 200")
return nil
}
}
}
func Wrap(a *app.App, f CntFunc) func(http.ResponseWriter, *http.Request) {
mid := ContTypeMid(LogMid(RedisMid(f)))
return func(w http.ResponseWriter, r *http.Request) {
mid(&Context{
App: a,
Res: w,
Req: r,
BufRes: newBufRes(),
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment