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

View File

@ -3,7 +3,6 @@ package common
import (
"bytes"
"encoding/json"
"sync"
)
func NewBool(t bool) *bool {
@ -67,30 +66,3 @@ func PrettyPrint(json_dirty []byte) []byte {
json_pretty.Write([]byte("\n"))
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"
)
var ETAGS SafeMapStringString = NewSafeMapStringString()
func StaticHandler(_path string) func(App, http.ResponseWriter, *http.Request) {
return func(ctx App, res http.ResponseWriter, req *http.Request) {
var base string = GetAbsolutePath(_path)
@ -95,16 +93,15 @@ func hashFile (path string, n int) string {
stat, err := f.Stat()
if err != nil {
return "UNKNOWN"
return ""
}
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) {
zFilePath := filePath + ".gz"
tags := ETAGS.Gets(filePath, zFilePath)
etagNormal := tags[0]
etagGzip := tags[1]
etagNormal := hashFile(filePath, 10)
etagGzip := hashFile(zFilePath, 10)
if 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 file, err := os.OpenFile(zFilePath, os.O_RDONLY, os.ModePerm); err == nil {
head.Set("Content-Encoding", "gzip")
if etagGzip == "" {
tag := hashFile(zFilePath, 10)
ETAGS.Set(zFilePath, tag)
head.Set("Etag", tag)
} else {
head.Set("Etag", etagGzip)
}
head.Set("Etag", etagGzip)
io.Copy(res, file)
file.Close()
return
@ -138,13 +129,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
http.NotFound(res, req)
return
}
if etagNormal == "" {
tag := hashFile(filePath, 10)
ETAGS.Set(filePath, tag)
head.Set("Etag", tag)
} else {
head.Set("Etag", etagNormal)
}
head.Set("Etag", etagNormal)
io.Copy(res, file)
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 == nil {
val = "/"
}
if val != conn["path"] {
continue
}