github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/cache/cache.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package cache
     7  
     8  import (
     9  	"fmt"
    10  	"strconv"
    11  
    12  	"github.com/gitbundle/modules/setting"
    13  
    14  	mc "gitea.com/go-chi/cache"
    15  
    16  	_ "gitea.com/go-chi/cache/memcache" // memcache plugin for cache
    17  )
    18  
    19  var conn mc.Cache
    20  
    21  func newCache(cacheConfig setting.Cache) (mc.Cache, error) {
    22  	return mc.NewCacher(mc.Options{
    23  		Adapter:       cacheConfig.Adapter,
    24  		AdapterConfig: cacheConfig.Conn,
    25  		Interval:      cacheConfig.Interval,
    26  	})
    27  }
    28  
    29  // NewContext start cache service
    30  func NewContext() error {
    31  	var err error
    32  
    33  	if conn == nil && setting.CacheService.Enabled {
    34  		if conn, err = newCache(setting.CacheService.Cache); err != nil {
    35  			return err
    36  		}
    37  		if err = conn.Ping(); err != nil {
    38  			return err
    39  		}
    40  	}
    41  
    42  	return err
    43  }
    44  
    45  // GetCache returns the currently configured cache
    46  func GetCache() mc.Cache {
    47  	return conn
    48  }
    49  
    50  // GetString returns the key value from cache with callback when no key exists in cache
    51  func GetString(key string, getFunc func() (string, error)) (string, error) {
    52  	if conn == nil || setting.CacheService.TTL == 0 {
    53  		return getFunc()
    54  	}
    55  	if !conn.IsExist(key) {
    56  		var (
    57  			value string
    58  			err   error
    59  		)
    60  		if value, err = getFunc(); err != nil {
    61  			return value, err
    62  		}
    63  		err = conn.Put(key, value, setting.CacheService.TTLSeconds())
    64  		if err != nil {
    65  			return "", err
    66  		}
    67  	}
    68  	value := conn.Get(key)
    69  	if v, ok := value.(string); ok {
    70  		return v, nil
    71  	}
    72  	if v, ok := value.(fmt.Stringer); ok {
    73  		return v.String(), nil
    74  	}
    75  	return fmt.Sprintf("%s", conn.Get(key)), nil
    76  }
    77  
    78  // GetInt returns key value from cache with callback when no key exists in cache
    79  func GetInt(key string, getFunc func() (int, error)) (int, error) {
    80  	if conn == nil || setting.CacheService.TTL == 0 {
    81  		return getFunc()
    82  	}
    83  	if !conn.IsExist(key) {
    84  		var (
    85  			value int
    86  			err   error
    87  		)
    88  		if value, err = getFunc(); err != nil {
    89  			return value, err
    90  		}
    91  		err = conn.Put(key, value, setting.CacheService.TTLSeconds())
    92  		if err != nil {
    93  			return 0, err
    94  		}
    95  	}
    96  	switch value := conn.Get(key).(type) {
    97  	case int:
    98  		return value, nil
    99  	case string:
   100  		v, err := strconv.Atoi(value)
   101  		if err != nil {
   102  			return 0, err
   103  		}
   104  		return v, nil
   105  	default:
   106  		return 0, fmt.Errorf("Unsupported cached value type: %v", value)
   107  	}
   108  }
   109  
   110  // GetInt64 returns key value from cache with callback when no key exists in cache
   111  func GetInt64(key string, getFunc func() (int64, error)) (int64, error) {
   112  	if conn == nil || setting.CacheService.TTL == 0 {
   113  		return getFunc()
   114  	}
   115  	if !conn.IsExist(key) {
   116  		var (
   117  			value int64
   118  			err   error
   119  		)
   120  		if value, err = getFunc(); err != nil {
   121  			return value, err
   122  		}
   123  		err = conn.Put(key, value, setting.CacheService.TTLSeconds())
   124  		if err != nil {
   125  			return 0, err
   126  		}
   127  	}
   128  	switch value := conn.Get(key).(type) {
   129  	case int64:
   130  		return value, nil
   131  	case string:
   132  		v, err := strconv.ParseInt(value, 10, 64)
   133  		if err != nil {
   134  			return 0, err
   135  		}
   136  		return v, nil
   137  	default:
   138  		return 0, fmt.Errorf("Unsupported cached value type: %v", value)
   139  	}
   140  }
   141  
   142  // Remove key from cache
   143  func Remove(key string) {
   144  	if conn == nil {
   145  		return
   146  	}
   147  	_ = conn.Delete(key)
   148  }