fix (concurrency): fix concurrency problem

This commit is contained in:
Mickael KERJEAN
2019-02-25 17:41:47 +11:00
parent 14e177026d
commit c9c3a9f5e2
4 changed files with 16 additions and 48 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/mitchellh/hashstructure" "github.com/mitchellh/hashstructure"
"github.com/patrickmn/go-cache" "github.com/patrickmn/go-cache"
"sync"
"time" "time"
) )
@ -60,6 +61,7 @@ func NewAppCache(arg ...time.Duration) AppCache {
type KeyValueStore struct { type KeyValueStore struct {
cache map[string]interface{} cache map[string]interface{}
sync.RWMutex
} }
func NewKeyValueStore() KeyValueStore { func NewKeyValueStore() KeyValueStore {
@ -67,13 +69,19 @@ func NewKeyValueStore() KeyValueStore {
} }
func (this KeyValueStore) Get(key string) interface{} { func (this KeyValueStore) Get(key string) interface{} {
this.RLock()
defer this.RUnlock()
return this.cache[key] return this.cache[key]
} }
func (this *KeyValueStore) Set(key string, value interface{}) { func (this *KeyValueStore) Set(key string, value interface{}) {
this.Lock()
defer this.Unlock()
this.cache[key] = value this.cache[key] = value
} }
func (this *KeyValueStore) Clear() { func (this *KeyValueStore) Clear() {
this.Lock()
defer this.Unlock()
this.cache = make(map[string]interface{}) this.cache = make(map[string]interface{})
} }

View File

@ -3,7 +3,6 @@ package common
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"sync"
) )
func NewBool(t bool) *bool { func NewBool(t bool) *bool {
@ -67,30 +66,3 @@ func PrettyPrint(json_dirty []byte) []byte {
json_pretty.Write([]byte("\n")) json_pretty.Write([]byte("\n"))
return json_pretty.Bytes() return json_pretty.Bytes()
} }
type SafeMapStringString struct {
sync.RWMutex
internal map[string]string
}
func NewSafeMapStringString() SafeMapStringString {
return SafeMapStringString{
internal: make(map[string]string),
}
}
func(this SafeMapStringString) Set(key string, value string) {
this.Lock()
this.internal[key] = value
this.Unlock()
}
func(this SafeMapStringString) Gets(keys ...string) []string{
this.RLock()
res := make([]string, len(keys))
for i, key := range keys {
res[i] = this.internal[key]
}
this.RUnlock()
return res
}

View File

@ -11,8 +11,6 @@ import (
"strings" "strings"
) )
var ETAGS SafeMapStringString = NewSafeMapStringString()
func StaticHandler(_path string) func(App, http.ResponseWriter, *http.Request) { func StaticHandler(_path string) func(App, http.ResponseWriter, *http.Request) {
return func(ctx App, res http.ResponseWriter, req *http.Request) { return func(ctx App, res http.ResponseWriter, req *http.Request) {
var base string = GetAbsolutePath(_path) var base string = GetAbsolutePath(_path)
@ -95,16 +93,15 @@ func hashFile (path string, n int) string {
stat, err := f.Stat() stat, err := f.Stat()
if err != nil { if err != nil {
return "UNKNOWN" return ""
} }
return QuickHash(fmt.Sprintf("%s %d %d %s", path, stat.Size(), stat.Mode(), stat.ModTime()), n) return QuickHash(fmt.Sprintf("%s %d %d %s", path, stat.Size(), stat.Mode(), stat.ModTime()), n)
} }
func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) { func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
zFilePath := filePath + ".gz" zFilePath := filePath + ".gz"
tags := ETAGS.Gets(filePath, zFilePath) etagNormal := hashFile(filePath, 10)
etagNormal := tags[0] etagGzip := hashFile(zFilePath, 10)
etagGzip := tags[1]
if req.Header.Get("If-None-Match") != "" { if req.Header.Get("If-None-Match") != "" {
browserTag := req.Header.Get("If-None-Match") browserTag := req.Header.Get("If-None-Match")
@ -120,13 +117,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") { if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
if file, err := os.OpenFile(zFilePath, os.O_RDONLY, os.ModePerm); err == nil { if file, err := os.OpenFile(zFilePath, os.O_RDONLY, os.ModePerm); err == nil {
head.Set("Content-Encoding", "gzip") head.Set("Content-Encoding", "gzip")
if etagGzip == "" { head.Set("Etag", etagGzip)
tag := hashFile(zFilePath, 10)
ETAGS.Set(zFilePath, tag)
head.Set("Etag", tag)
} else {
head.Set("Etag", etagGzip)
}
io.Copy(res, file) io.Copy(res, file)
file.Close() file.Close()
return return
@ -138,13 +129,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
http.NotFound(res, req) http.NotFound(res, req)
return return
} }
if etagNormal == "" { head.Set("Etag", etagNormal)
tag := hashFile(filePath, 10)
ETAGS.Set(filePath, tag)
head.Set("Etag", tag)
} else {
head.Set("Etag", etagNormal)
}
io.Copy(res, file) io.Copy(res, file)
file.Close() file.Close()
} }

View File

@ -23,6 +23,9 @@ func NewBackend(ctx *App, conn map[string]string) (IBackend, error) {
} }
} }
if val, ok := d["path"]; ok == true { if val, ok := d["path"]; ok == true {
if val == nil {
val = "/"
}
if val != conn["path"] { if val != conn["path"] {
continue continue
} }