dashboard: split key handler into key package, add TimeKey to cache
LGTM=dsymonds R=golang-codereviews, dsymonds CC=golang-codereviews https://golang.org/cl/104780044
This commit is contained in:
parent
222283a9c8
commit
707c7629cb
|
@ -20,6 +20,7 @@ import (
|
||||||
"appengine/datastore"
|
"appengine/datastore"
|
||||||
|
|
||||||
"cache"
|
"cache"
|
||||||
|
"key"
|
||||||
)
|
)
|
||||||
|
|
||||||
const commitsPerPage = 30
|
const commitsPerPage = 30
|
||||||
|
@ -789,12 +790,12 @@ func validKey(c appengine.Context, key, builder string) bool {
|
||||||
return isMasterKey(c, key) || key == builderKey(c, builder)
|
return isMasterKey(c, key) || key == builderKey(c, builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isMasterKey(c appengine.Context, key string) bool {
|
func isMasterKey(c appengine.Context, k string) bool {
|
||||||
return appengine.IsDevAppServer() || key == secretKey(c)
|
return appengine.IsDevAppServer() || k == key.Secret(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func builderKey(c appengine.Context, builder string) string {
|
func builderKey(c appengine.Context, builder string) string {
|
||||||
h := hmac.New(md5.New, []byte(secretKey(c)))
|
h := hmac.New(md5.New, []byte(key.Secret(c)))
|
||||||
h.Write([]byte(builder))
|
h.Write([]byte(builder))
|
||||||
return fmt.Sprintf("%x", h.Sum(nil))
|
return fmt.Sprintf("%x", h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@ import (
|
||||||
|
|
||||||
"appengine"
|
"appengine"
|
||||||
"appengine/datastore"
|
"appengine/datastore"
|
||||||
|
|
||||||
"cache"
|
"cache"
|
||||||
|
"key"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initHandler(w http.ResponseWriter, r *http.Request) {
|
func initHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -38,7 +40,7 @@ func initHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create secret key.
|
// Create secret key.
|
||||||
secretKey(c)
|
key.Secret(c)
|
||||||
|
|
||||||
fmt.Fprint(w, "OK")
|
fmt.Fprint(w, "OK")
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,11 @@ import (
|
||||||
"appengine/memcache"
|
"appengine/memcache"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TimeKey specifies the memcache entity that keeps the logical datastore time.
|
||||||
|
var TimeKey = "cachetime"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
nocache = "nocache"
|
nocache = "nocache"
|
||||||
timeKey = "cachetime"
|
|
||||||
expiry = 600 // 10 minutes
|
expiry = 600 // 10 minutes
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ func newTime() uint64 { return uint64(time.Now().Unix()) << 32 }
|
||||||
|
|
||||||
// Now returns the current logical datastore time to use for cache lookups.
|
// Now returns the current logical datastore time to use for cache lookups.
|
||||||
func Now(c appengine.Context) uint64 {
|
func Now(c appengine.Context) uint64 {
|
||||||
t, err := memcache.Increment(c, timeKey, 0, newTime())
|
t, err := memcache.Increment(c, TimeKey, 0, newTime())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Errorf("cache.Now: %v", err)
|
c.Errorf("cache.Now: %v", err)
|
||||||
return 0
|
return 0
|
||||||
|
@ -36,7 +38,7 @@ func Now(c appengine.Context) uint64 {
|
||||||
// Tick sets the current logical datastore time to a never-before-used time
|
// Tick sets the current logical datastore time to a never-before-used time
|
||||||
// and returns that time. It should be called to invalidate the cache.
|
// and returns that time. It should be called to invalidate the cache.
|
||||||
func Tick(c appengine.Context) uint64 {
|
func Tick(c appengine.Context) uint64 {
|
||||||
t, err := memcache.Increment(c, timeKey, 1, newTime())
|
t, err := memcache.Increment(c, TimeKey, 1, newTime())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Errorf("cache.Tick: %v", err)
|
c.Errorf("cache.Tick: %v", err)
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// +build appengine
|
// +build appengine
|
||||||
|
|
||||||
package build
|
package key
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -15,18 +15,18 @@ import (
|
||||||
|
|
||||||
var theKey struct {
|
var theKey struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
BuilderKey
|
builderKey
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuilderKey struct {
|
type builderKey struct {
|
||||||
Secret string
|
Secret string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *BuilderKey) Key(c appengine.Context) *datastore.Key {
|
func (k *builderKey) Key(c appengine.Context) *datastore.Key {
|
||||||
return datastore.NewKey(c, "BuilderKey", "root", 0, nil)
|
return datastore.NewKey(c, "BuilderKey", "root", 0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func secretKey(c appengine.Context) string {
|
func Secret(c appengine.Context) string {
|
||||||
// check with rlock
|
// check with rlock
|
||||||
theKey.RLock()
|
theKey.RLock()
|
||||||
k := theKey.Secret
|
k := theKey.Secret
|
||||||
|
@ -43,7 +43,7 @@ func secretKey(c appengine.Context) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill
|
// fill
|
||||||
if err := datastore.Get(c, theKey.Key(c), &theKey.BuilderKey); err != nil {
|
if err := datastore.Get(c, theKey.Key(c), &theKey.builderKey); err != nil {
|
||||||
if err == datastore.ErrNoSuchEntity {
|
if err == datastore.ErrNoSuchEntity {
|
||||||
// If the key is not stored in datastore, write it.
|
// If the key is not stored in datastore, write it.
|
||||||
// This only happens at the beginning of a new deployment.
|
// This only happens at the beginning of a new deployment.
|
||||||
|
@ -54,7 +54,7 @@ func secretKey(c appengine.Context) string {
|
||||||
panic("lost key from datastore")
|
panic("lost key from datastore")
|
||||||
}
|
}
|
||||||
theKey.Secret = "gophers rule"
|
theKey.Secret = "gophers rule"
|
||||||
datastore.Put(c, theKey.Key(c), &theKey.BuilderKey)
|
datastore.Put(c, theKey.Key(c), &theKey.builderKey)
|
||||||
return theKey.Secret
|
return theKey.Secret
|
||||||
}
|
}
|
||||||
panic("cannot load builder key: " + err.Error())
|
panic("cannot load builder key: " + err.Error())
|
Loading…
Reference in New Issue