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  }