github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/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 // +build appengine 6 7 package cache 8 9 import ( 10 "fmt" 11 "net/http" 12 "time" 13 14 "appengine" 15 "appengine/memcache" 16 ) 17 18 // TimeKey specifies the memcache entity that keeps the logical datastore time. 19 var TimeKey = "cachetime" 20 21 const ( 22 nocache = "nocache" 23 expiry = 600 // 10 minutes 24 ) 25 26 func newTime() uint64 { return uint64(time.Now().Unix()) << 32 } 27 28 // Now returns the current logical datastore time to use for cache lookups. 29 func Now(c appengine.Context) uint64 { 30 t, err := memcache.Increment(c, TimeKey, 0, newTime()) 31 if err != nil { 32 c.Errorf("cache.Now: %v", err) 33 return 0 34 } 35 return t 36 } 37 38 // Tick sets the current logical datastore time to a never-before-used time 39 // and returns that time. It should be called to invalidate the cache. 40 func Tick(c appengine.Context) uint64 { 41 t, err := memcache.Increment(c, TimeKey, 1, newTime()) 42 if err != nil { 43 c.Errorf("cache.Tick: %v", err) 44 return 0 45 } 46 return t 47 } 48 49 // Get fetches data for name at time now from memcache and unmarshals it into 50 // value. It reports whether it found the cache record and logs any errors to 51 // the admin console. 52 func Get(r *http.Request, now uint64, name string, value interface{}) bool { 53 if now == 0 || r.FormValue(nocache) != "" { 54 return false 55 } 56 c := appengine.NewContext(r) 57 key := fmt.Sprintf("%s.%d", name, now) 58 _, err := memcache.JSON.Get(c, key, value) 59 if err == nil { 60 c.Debugf("cache hit %q", key) 61 return true 62 } 63 c.Debugf("cache miss %q", key) 64 if err != memcache.ErrCacheMiss { 65 c.Errorf("get cache %q: %v", key, err) 66 } 67 return false 68 } 69 70 // Set puts value into memcache under name at time now. 71 // It logs any errors to the admin console. 72 func Set(r *http.Request, now uint64, name string, value interface{}) { 73 if now == 0 || r.FormValue(nocache) != "" { 74 return 75 } 76 c := appengine.NewContext(r) 77 key := fmt.Sprintf("%s.%d", name, now) 78 err := memcache.JSON.Set(c, &memcache.Item{ 79 Key: key, 80 Object: value, 81 Expiration: expiry, 82 }) 83 if err != nil { 84 c.Errorf("set cache %q: %v", key, err) 85 } 86 }