Guest User

Go test

a guest
Feb 12th, 2015
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.24 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "database/sql"
  5.     "errors"
  6.     "github.com/bradfitz/gomemcache/memcache"
  7.     _ "github.com/go-sql-driver/mysql"
  8.     "html"
  9.     "log"
  10.     "net/http"
  11.     "runtime"
  12.     "strconv"
  13.     "strings"
  14. )
  15.  
  16. const (
  17.     listen             = "127.0.0.1:12345"
  18.     mysqlConnection    = "dbuser:dbpass@tcp(dbhost:3306)/dbname"
  19.     maxConnectionCount = 256
  20.     storySelect        = "SELECT data FROM stories WHERE id = ?"
  21. )
  22.  
  23. var (
  24.     storyStatement      *sql.Stmt
  25.     memcachedConnection = []string{"10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212"}
  26.     mc                  *memcache.Client
  27.  
  28.     pong_str = []byte("pong: ")
  29. )
  30.  
  31. func main() {
  32.     runtime.GOMAXPROCS(runtime.NumCPU())
  33.  
  34.     mc = memcache.New(memcachedConnection...)
  35.  
  36.     db, err := sql.Open("mysql", mysqlConnection)
  37.     if err != nil {
  38.         log.Fatalf("Error opening database: %v", err)
  39.     }
  40.  
  41.     db.SetMaxIdleConns(maxConnectionCount)
  42.  
  43.     storyStatement, err = db.Prepare(storySelect)
  44.     if err != nil {
  45.         log.Fatal(err)
  46.     }
  47.  
  48.     http.HandleFunc("/ping", pingHandler)
  49.     http.HandleFunc("/story/", storyHandler)
  50.     http.ListenAndServe(listen, nil)
  51. }
  52.  
  53. func pingHandler(w http.ResponseWriter, r *http.Request) {
  54.  
  55.     var rNum uint64
  56.     var err error
  57.  
  58.     if rStr := r.URL.Query().Get("r"); len(rStr) > 0 {
  59.         rNum, err = strconv.ParseUint(rStr, 10, 0)
  60.     } else {
  61.         err = errors.New("r parametr do not exist")
  62.     }
  63.  
  64.     if err != nil {
  65.         w.Header().Set("Content-Type", "text/plain")
  66.         w.WriteHeader(404)
  67.         w.Write([]byte(err.Error()))
  68.         return
  69.     }
  70.  
  71.     rNum++
  72.  
  73.     w.Header().Set("Content-Type", "text/plain")
  74.     w.Write(strconv.AppendUint(pong_str, rNum, 10))
  75. }
  76.  
  77. func storyHandler(w http.ResponseWriter, r *http.Request) {
  78.  
  79.     var story_id uint64
  80.     var story_id_str string
  81.     var err error
  82.  
  83.     if rStr, story_len := r.URL.Path, len("/story/"); len(rStr) > story_len {
  84.         story_id_str = rStr[story_len:]
  85.         story_id, err = strconv.ParseUint(story_id_str, 10, 0)
  86.     } else {
  87.         err = errors.New("Story Id do not exist")
  88.     }
  89.  
  90.     if err != nil {
  91.         w.Header().Set("Content-Type", "text/plain")
  92.         w.WriteHeader(404)
  93.         w.Write([]byte(err.Error()))
  94.         return
  95.     }
  96.  
  97.     w.Header().Set("Content-Type", "text/html")
  98.     var story []byte
  99.  
  100.     if item, err := mc.Get(story_id_str); err != nil || len(item.Value) == 0 {
  101.  
  102.         var story_str string
  103.         err = storyStatement.QueryRow(story_id).Scan(&story_str)
  104.         if err != nil {
  105.             log.Printf("Error scanning story row. Id:%d, erroro: %s", story_id,  err.Error())
  106.             story = []byte("Story not fount")
  107.  
  108.             w.WriteHeader(404)
  109.  
  110.         } else {
  111.             story_str = html.EscapeString(story_str)
  112.  
  113.             strings.Replace(story_str, "\n", "<br>", -1)
  114.  
  115.             story = []byte(story_str) // ToDo избавиться от копирования памяти и от лишней переменной story_str
  116.  
  117.         }
  118.         err = mc.Set(&memcache.Item{Key: story_id_str, Value: story, Expiration:1}) // ToDo использовать item из Get(), если он не nil
  119.         if err != nil {
  120.             log.Printf("Can not set key: %s", err.Error())
  121.         }
  122.  
  123.     } else {
  124.         story = item.Value
  125.     }
  126.  
  127.     // ToDo переписать через append() или var buffer bytes.Buffer + buffer.WriteString(s2)
  128.     w.Write([]byte("<!doctype html>\n<html>\n<head>\n<title>Story " + story_id_str + "</title>\n</head>\n<body>"))
  129.     w.Write(story)
  130.     w.Write([]byte("</body>\n</html>"))
  131. }
Advertisement
Add Comment
Please, Sign In to add comment