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  }