Browse Source

Added a Context type for non-global contexts.

Implemented the current globalContext using the new type.
Kamil Kisiel 13 years ago
parent
commit
bbd3ed3168
1 changed files with 61 additions and 33 deletions
  1. +61
    -33
      context.go

+ 61
- 33
context.go View File

@ -10,39 +10,59 @@ import (
"time"
)
var (
mutex sync.Mutex
data = make(map[*http.Request]map[interface{}]interface{})
datat = make(map[*http.Request]int64)
)
var globalContext *Context = NewContext()
type Context struct {
mutex sync.RWMutex
data map[*http.Request]map[interface{}]interface{}
datat map[*http.Request]int64
}
func NewContext() *Context {
data := make(map[*http.Request]map[interface{}]interface{})
datat := make(map[*http.Request]int64)
return &Context{data: data, datat: datat}
}
// Set stores a value for a given key in a given request.
func Set(r *http.Request, key, val interface{}) {
mutex.Lock()
defer mutex.Unlock()
if data[r] == nil {
data[r] = make(map[interface{}]interface{})
datat[r] = time.Now().Unix()
globalContext.Set(r, key, val)
}
func (c *Context) Set(r *http.Request, key, val interface{}) {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.data[r] == nil {
c.data[r] = make(map[interface{}]interface{})
c.datat[r] = time.Now().Unix()
}
data[r][key] = val
c.data[r][key] = val
}
// Get returns a value stored for a given key in a given request.
func Get(r *http.Request, key interface{}) interface{} {
mutex.Lock()
defer mutex.Unlock()
if data[r] != nil {
return data[r][key]
return globalContext.Get(r, key)
}
func (c *Context) Get(r *http.Request, key interface{}) interface{} {
c.mutex.RLock()
defer c.mutex.RUnlock()
if c.data[r] != nil {
return c.data[r][key]
}
return nil
}
// Delete removes a value stored for a given key in a given request.
func Delete(r *http.Request, key interface{}) {
mutex.Lock()
defer mutex.Unlock()
if data[r] != nil {
delete(data[r], key)
globalContext.Delete(r, key)
}
func (c *Context) Delete(r *http.Request, key interface{}) {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.data[r] != nil {
delete(c.data[r], key)
}
}
@ -51,15 +71,19 @@ func Delete(r *http.Request, key interface{}) {
// This is usually called by a handler wrapper to clean up request
// variables at the end of a request lifetime. See ClearHandler().
func Clear(r *http.Request) {
mutex.Lock()
defer mutex.Unlock()
clear(r)
globalContext.Clear(r)
}
func (c *Context) Clear(r *http.Request) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.clear(r)
}
// clear is Clear without the lock.
func clear(r *http.Request) {
delete(data, r)
delete(datat, r)
func (c *Context) clear(r *http.Request) {
delete(c.data, r)
delete(c.datat, r)
}
// Purge removes request data stored for longer than maxAge, in seconds.
@ -72,18 +96,22 @@ func clear(r *http.Request) {
// amount of memory. In case this is detected, Purge() must be called
// periodically until the problem is fixed.
func Purge(maxAge int) int {
mutex.Lock()
defer mutex.Unlock()
return globalContext.Purge(maxAge)
}
func (c *Context) Purge(maxAge int) int {
c.mutex.Lock()
defer c.mutex.Unlock()
count := 0
if maxAge <= 0 {
count = len(data)
data = make(map[*http.Request]map[interface{}]interface{})
datat = make(map[*http.Request]int64)
count = len(c.data)
c.data = make(map[*http.Request]map[interface{}]interface{})
c.datat = make(map[*http.Request]int64)
} else {
min := time.Now().Unix() - int64(maxAge)
for r, _ := range data {
if datat[r] < min {
clear(r)
for r, _ := range c.data {
if c.datat[r] < min {
c.clear(r)
count++
}
}


Loading…
Cancel
Save