step-7
parent
2c4f868371
commit
2da67f7bac
|
@ -19,6 +19,7 @@ type ErrorMsg struct{
|
|||
const (
|
||||
REQUEST_BODY_SIZE = 1024 * 30
|
||||
MAX_REQUEST_COUNT = 20
|
||||
BIN_LIFETIME = 60 * 60 * 24 * 2
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -26,7 +27,7 @@ type Config struct {
|
|||
}
|
||||
|
||||
func GetApi(config *Config) *martini.ClassicMartini {
|
||||
storage := NewMemoryStorage(MAX_REQUEST_COUNT)
|
||||
storage := NewMemoryStorage(MAX_REQUEST_COUNT, BIN_LIFETIME)
|
||||
store := sessions.NewCookieStore([]byte(config.SessionSecret))
|
||||
|
||||
api := martini.Classic()
|
||||
|
|
|
@ -3,12 +3,14 @@ package skimmer
|
|||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MemoryStorage struct {
|
||||
BaseStorage
|
||||
sync.RWMutex
|
||||
binRecords map[string]*BinRecord
|
||||
cleanTimer *time.Timer
|
||||
}
|
||||
|
||||
type BinRecord struct {
|
||||
|
@ -30,13 +32,40 @@ func (binRecord *BinRecord) ShrinkRequests(size int) {
|
|||
}
|
||||
}
|
||||
|
||||
func NewMemoryStorage(maxRequests int) *MemoryStorage {
|
||||
return &MemoryStorage{
|
||||
func NewMemoryStorage(maxRequests int, binLifetime int64) *MemoryStorage {
|
||||
storage := &MemoryStorage{
|
||||
BaseStorage{
|
||||
maxRequests: maxRequests,
|
||||
binLifetime: binLifetime,
|
||||
},
|
||||
sync.RWMutex{},
|
||||
map[string]*BinRecord{},
|
||||
&time.Timer{},
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
func (storage *MemoryStorage) StartCleaning(timeout int) {
|
||||
defer func(){
|
||||
storage.cleanTimer = time.AfterFunc(time.Duration(timeout) * time.Second, func(){storage.StartCleaning(timeout)})
|
||||
}()
|
||||
storage.clean()
|
||||
}
|
||||
|
||||
func (storage *MemoryStorage) StopCleaning() {
|
||||
if storage.cleanTimer != nil {
|
||||
storage.cleanTimer.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (storage *MemoryStorage) clean() {
|
||||
storage.Lock()
|
||||
defer storage.Unlock()
|
||||
now := time.Now().Unix()
|
||||
for name, binRecord := range storage.binRecords {
|
||||
if binRecord.bin.Updated < (now - storage.binLifetime) {
|
||||
delete(storage.binRecords, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +154,7 @@ func (storage *MemoryStorage) CreateRequest(bin *Bin, req *Request) error {
|
|||
binRecord.requestMap[req.Id] = req
|
||||
binRecord.ShrinkRequests(storage.maxRequests)
|
||||
binRecord.bin.RequestCount = len(binRecord.requests)
|
||||
binRecord.bin.Updated = time.Now().Unix()
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
|
|
|
@ -5,16 +5,17 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"bytes"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
func getMemoryStorage() *MemoryStorage {
|
||||
return NewMemoryStorage(REQUEST_BODY_SIZE)
|
||||
return NewMemoryStorage(REQUEST_BODY_SIZE, BIN_LIFETIME)
|
||||
}
|
||||
|
||||
func TestNewMemoryStorage(t *testing.T) {
|
||||
maxRequests := 20
|
||||
storage := NewMemoryStorage(maxRequests)
|
||||
storage := NewMemoryStorage(maxRequests, BIN_LIFETIME)
|
||||
|
||||
assert.Equal(t, storage.maxRequests, maxRequests)
|
||||
assert.NotNil(t, storage.binRecords)
|
||||
|
@ -103,7 +104,7 @@ func TestLookupBins(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateRequest(t *testing.T) {
|
||||
storage := NewMemoryStorage(2)
|
||||
storage := NewMemoryStorage(2, BIN_LIFETIME)
|
||||
bin := NewBin()
|
||||
storage.CreateBin(bin)
|
||||
httpRequest, _ := http.NewRequest("GET", "/", bytes.NewBuffer([]byte("body")))
|
||||
|
@ -203,3 +204,21 @@ func TestLookupRequests(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMemoryClean(t *testing.T) {
|
||||
storage := NewMemoryStorage(2, -1)
|
||||
bin := NewBin()
|
||||
storage.CreateBin(bin)
|
||||
assert.Equal(t, storage.binRecords[bin.Name].bin, bin)
|
||||
storage.clean()
|
||||
assert.Equal(t, len(storage.binRecords), 0)
|
||||
|
||||
storage.CreateBin(bin)
|
||||
assert.Equal(t, storage.binRecords[bin.Name].bin, bin)
|
||||
storage.StartCleaning(0)
|
||||
assert.Equal(t, len(storage.binRecords), 0)
|
||||
storage.CreateBin(bin)
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
assert.Equal(t, len(storage.binRecords), 0)
|
||||
storage.StopCleaning()
|
||||
}
|
||||
|
|
|
@ -12,4 +12,5 @@ type Storage interface {
|
|||
|
||||
type BaseStorage struct {
|
||||
maxRequests int
|
||||
binLifetime int64
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue