github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/misc/dashboard/app/cache/cache.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cache 6 7 import ( 8 "fmt" 9 "net/http" 10 "time" 11 12 "appengine" 13 "appengine/memcache" 14 ) 15 16 const ( 17 nocache = "nocache" 18 timeKey = "cachetime" 19 expiry = 600 // 10 minutes 20 ) 21 22 func newTime() uint64 { return uint64(time.Now().Unix()) << 32 } 23 24 // Now returns the current logical datastore time to use for cache lookups. 25 func Now(c appengine.Context) uint64 { 26 t, err := memcache.Increment(c, timeKey, 0, newTime()) 27 if err != nil { 28 c.Errorf("cache.Now: %v", err) 29 return 0 30 } 31 return t 32 } 33 34 // Tick sets the current logical datastore time to a never-before-used time 35 // and returns that time. It should be called to invalidate the cache. 36 func Tick(c appengine.Context) uint64 { 37 t, err := memcache.Increment(c, timeKey, 1, newTime()) 38 if err != nil { 39 c.Errorf("cache.Tick: %v", err) 40 return 0 41 } 42 return t 43 } 44 45 // Get fetches data for name at time now from memcache and unmarshals it into 46 // value. It reports whether it found the cache record and logs any errors to 47 // the admin console. 48 func Get(r *http.Request, now uint64, name string, value interface{}) bool { 49 if now == 0 || r.FormValue(nocache) != "" { 50 return false 51 } 52 c := appengine.NewContext(r) 53 key := fmt.Sprintf("%s.%d", name, now) 54 _, err := memcache.JSON.Get(c, key, value) 55 if err == nil { 56 c.Debugf("cache hit %q", key) 57 return true 58 } 59 c.Debugf("cache miss %q", key) 60 if err != memcache.ErrCacheMiss { 61 c.Errorf("get cache %q: %v", key, err) 62 } 63 return false 64 } 65 66 // Set puts value into memcache under name at time now. 67 // It logs any errors to the admin console. 68 func Set(r *http.Request, now uint64, name string, value interface{}) { 69 if now == 0 || r.FormValue(nocache) != "" { 70 return 71 } 72 c := appengine.NewContext(r) 73 key := fmt.Sprintf("%s.%d", name, now) 74 err := memcache.JSON.Set(c, &memcache.Item{ 75 Key: key, 76 Object: value, 77 Expiration: expiry, 78 }) 79 if err != nil { 80 c.Errorf("set cache %q: %v", key, err) 81 } 82 }