123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gfile
- import (
- "context"
- "time"
- "github.com/gogf/gf/v2/errors/gcode"
- "github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/internal/command"
- "github.com/gogf/gf/v2/internal/intlog"
- "github.com/gogf/gf/v2/os/gcache"
- "github.com/gogf/gf/v2/os/gfsnotify"
- )
- const (
- defaultCacheDuration = "1m" // defaultCacheExpire is the expire time for file content caching in seconds.
- commandEnvKeyForCache = "gf.gfile.cache" // commandEnvKeyForCache is the configuration key for command argument or environment configuring cache expire duration.
- )
- var (
- // Default expire time for file content caching.
- cacheDuration = getCacheDuration()
- // internalCache is the memory cache for internal usage.
- internalCache = gcache.New()
- )
- func getCacheDuration() time.Duration {
- cacheDurationConfigured := command.GetOptWithEnv(commandEnvKeyForCache, defaultCacheDuration)
- d, err := time.ParseDuration(cacheDurationConfigured)
- if err != nil {
- panic(gerror.WrapCodef(
- gcode.CodeInvalidConfiguration,
- err,
- `error parsing string "%s" to time duration`,
- cacheDurationConfigured,
- ))
- }
- return d
- }
- // GetContentsWithCache returns string content of given file by `path` from cache.
- // If there's no content in the cache, it will read it from disk file specified by `path`.
- // The parameter `expire` specifies the caching time for this file content in seconds.
- func GetContentsWithCache(path string, duration ...time.Duration) string {
- return string(GetBytesWithCache(path, duration...))
- }
- // GetBytesWithCache returns []byte content of given file by `path` from cache.
- // If there's no content in the cache, it will read it from disk file specified by `path`.
- // The parameter `expire` specifies the caching time for this file content in seconds.
- func GetBytesWithCache(path string, duration ...time.Duration) []byte {
- var (
- ctx = context.Background()
- expire = cacheDuration
- cacheKey = commandEnvKeyForCache + path
- )
- if len(duration) > 0 {
- expire = duration[0]
- }
- r, _ := internalCache.GetOrSetFuncLock(ctx, cacheKey, func(ctx context.Context) (interface{}, error) {
- b := GetBytes(path)
- if b != nil {
- // Adding this `path` to gfsnotify,
- // it will clear its cache if there's any changes of the file.
- _, _ = gfsnotify.Add(path, func(event *gfsnotify.Event) {
- _, err := internalCache.Remove(ctx, cacheKey)
- if err != nil {
- intlog.Errorf(ctx, `%+v`, err)
- }
- gfsnotify.Exit()
- })
- }
- return b, nil
- }, expire)
- if r != nil {
- return r.Bytes()
- }
- return nil
- }
|