loading up the forgejo repo on tangled to test page performance
at forgejo 3.9 kB view raw
1// Copyright 2017 The Gitea Authors. All rights reserved. 2// SPDX-License-Identifier: MIT 3 4package cache 5 6import ( 7 "fmt" 8 "strconv" 9 "time" 10 11 "forgejo.org/modules/setting" 12 13 mc "code.forgejo.org/go-chi/cache" 14 15 _ "code.forgejo.org/go-chi/cache/memcache" // memcache plugin for cache 16) 17 18var conn mc.Cache 19 20func newCache(cacheConfig setting.Cache) (mc.Cache, error) { 21 return mc.NewCacher(mc.Options{ 22 Adapter: cacheConfig.Adapter, 23 AdapterConfig: cacheConfig.Conn, 24 Interval: cacheConfig.Interval, 25 }) 26} 27 28// Init start cache service 29func Init() error { 30 var err error 31 32 if conn == nil { 33 if conn, err = newCache(setting.CacheService.Cache); err != nil { 34 return err 35 } 36 if err = conn.Ping(); err != nil { 37 return err 38 } 39 } 40 41 return err 42} 43 44const ( 45 testCacheKey = "DefaultCache.TestKey" 46 SlowCacheThreshold = 100 * time.Microsecond 47) 48 49func Test() (time.Duration, error) { 50 if conn == nil { 51 return 0, fmt.Errorf("default cache not initialized") 52 } 53 54 testData := fmt.Sprintf("%x", make([]byte, 500)) 55 56 start := time.Now() 57 58 if err := conn.Delete(testCacheKey); err != nil { 59 return 0, fmt.Errorf("expect cache to delete data based on key if exist but got: %w", err) 60 } 61 if err := conn.Put(testCacheKey, testData, 10); err != nil { 62 return 0, fmt.Errorf("expect cache to store data but got: %w", err) 63 } 64 testVal := conn.Get(testCacheKey) 65 if testVal == nil { 66 return 0, fmt.Errorf("expect cache hit but got none") 67 } 68 if testVal != testData { 69 return 0, fmt.Errorf("expect cache to return same value as stored but got other") 70 } 71 72 return time.Since(start), nil 73} 74 75// GetCache returns the currently configured cache 76func GetCache() mc.Cache { 77 return conn 78} 79 80// GetString returns the key value from cache with callback when no key exists in cache 81func GetString(key string, getFunc func() (string, error)) (string, error) { 82 if conn == nil || setting.CacheService.TTL == 0 { 83 return getFunc() 84 } 85 86 cached := conn.Get(key) 87 88 if cached == nil { 89 value, err := getFunc() 90 if err != nil { 91 return value, err 92 } 93 return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) 94 } 95 96 if value, ok := cached.(string); ok { 97 return value, nil 98 } 99 100 if stringer, ok := cached.(fmt.Stringer); ok { 101 return stringer.String(), nil 102 } 103 104 return fmt.Sprintf("%s", cached), nil 105} 106 107// GetInt returns key value from cache with callback when no key exists in cache 108func GetInt(key string, getFunc func() (int, error)) (int, error) { 109 if conn == nil || setting.CacheService.TTL == 0 { 110 return getFunc() 111 } 112 113 cached := conn.Get(key) 114 115 if cached == nil { 116 value, err := getFunc() 117 if err != nil { 118 return value, err 119 } 120 121 return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) 122 } 123 124 switch v := cached.(type) { 125 case int: 126 return v, nil 127 case string: 128 value, err := strconv.Atoi(v) 129 if err != nil { 130 return 0, err 131 } 132 return value, nil 133 default: 134 value, err := getFunc() 135 if err != nil { 136 return value, err 137 } 138 return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) 139 } 140} 141 142// GetInt64 returns key value from cache with callback when no key exists in cache 143func GetInt64(key string, getFunc func() (int64, error)) (int64, error) { 144 if conn == nil || setting.CacheService.TTL == 0 { 145 return getFunc() 146 } 147 148 cached := conn.Get(key) 149 150 if cached == nil { 151 value, err := getFunc() 152 if err != nil { 153 return value, err 154 } 155 156 return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) 157 } 158 159 switch v := conn.Get(key).(type) { 160 case int64: 161 return v, nil 162 case string: 163 value, err := strconv.ParseInt(v, 10, 64) 164 if err != nil { 165 return 0, err 166 } 167 return value, nil 168 default: 169 value, err := getFunc() 170 if err != nil { 171 return value, err 172 } 173 174 return value, conn.Put(key, value, setting.CacheService.TTLSeconds()) 175 } 176} 177 178// Remove key from cache 179func Remove(key string) { 180 if conn == nil { 181 return 182 } 183 _ = conn.Delete(key) 184}