github.com/zhongdalu/gf@v1.0.0/g/os/gfcache/gfcache.go (about)

     1  // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/zhongdalu/gf.
     6  
     7  // Package gfcache provides reading and caching for file contents.
     8  package gfcache
     9  
    10  import (
    11  	"time"
    12  
    13  	"github.com/zhongdalu/gf/g/internal/cmdenv"
    14  	"github.com/zhongdalu/gf/g/os/gcache"
    15  	"github.com/zhongdalu/gf/g/os/gfile"
    16  	"github.com/zhongdalu/gf/g/os/gfsnotify"
    17  )
    18  
    19  const (
    20  	// Default expire time for file content caching in seconds.
    21  	gDEFAULT_CACHE_EXPIRE = 60
    22  )
    23  
    24  var (
    25  	// Default expire time for file content caching in seconds.
    26  	cacheExpire = cmdenv.Get("gf.gfcache.expire", gDEFAULT_CACHE_EXPIRE).Int() * 1000
    27  )
    28  
    29  // GetContents returns string content of given file by <path> from cache.
    30  // If there's no content in the cache, it will read it from disk file specified by <path>.
    31  // The parameter <expire> specifies the caching time for this file content in seconds.
    32  func GetContents(path string, duration ...interface{}) string {
    33  	return string(GetBinContents(path, duration...))
    34  }
    35  
    36  // GetBinContents returns []byte content of given file by <path> from cache.
    37  // If there's no content in the cache, it will read it from disk file specified by <path>.
    38  // The parameter <expire> specifies the caching time for this file content in seconds.
    39  func GetBinContents(path string, duration ...interface{}) []byte {
    40  	k := cacheKey(path)
    41  	e := cacheExpire
    42  	if len(duration) > 0 {
    43  		e = getSecondExpire(duration[0])
    44  	}
    45  	r := gcache.GetOrSetFuncLock(k, func() interface{} {
    46  		b := gfile.GetBinContents(path)
    47  		if b != nil {
    48  			// Adding this <path> to gfsnotify,
    49  			// it will clear its cache if there's any changes of the file.
    50  			_, _ = gfsnotify.Add(path, func(event *gfsnotify.Event) {
    51  				gcache.Remove(k)
    52  				gfsnotify.Exit()
    53  			})
    54  		}
    55  		return b
    56  	}, e*1000)
    57  	if r != nil {
    58  		return r.([]byte)
    59  	}
    60  	return nil
    61  }
    62  
    63  // getSecondExpire converts parameter <duration> to int type in seconds.
    64  //
    65  // Note that there's some performance cost in type assertion here, but it's valuable.
    66  func getSecondExpire(duration interface{}) int {
    67  	if d, ok := duration.(time.Duration); ok {
    68  		return int(d.Nanoseconds() / 1000000000)
    69  	} else {
    70  		return duration.(int)
    71  	}
    72  }
    73  
    74  // cacheKey produces the cache key for gcache.
    75  func cacheKey(path string) string {
    76  	return "gf.gfcache:" + path
    77  }