Files
Gitea/modules/cache/cache_memcache.go
T
silverwind bea6fcaa84 refactor: move go-chi/cache into Gitea (#39530)
The `gitea.com/go-chi/cache` package only exists for Gitea, so it moves
into `modules/cache`.

- `ITEM_TTL = -1` disables caching as documented
- Sub-second TTLs round up instead of never expiring
- The Redis adapter no longer grows a `MacaronCache` hash
- Use two-queue cache for in-memory cache

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-02 18:16:34 +02:00

71 lines
1.7 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cache
import (
"errors"
"fmt"
"math"
"strings"
"github.com/bradfitz/gomemcache/memcache"
)
const memcacheMaxRelativeTTL = 30 * 24 * 60 * 60
type memcacheCache struct {
client *memcache.Client
}
func newMemcacheCache(conn string) (backend, error) {
if conn == "" {
return nil, errors.New("cache adapter memcache requires [cache] HOST, e.g. 127.0.0.1:11211")
}
servers := &memcache.ServerList{}
if err := servers.SetServers(strings.Split(conn, ";")...); err != nil {
return nil, fmt.Errorf("invalid memcache HOST %q: %w", conn, err)
}
return &memcacheCache{client: memcache.NewFromSelector(servers)}, nil
}
// memcacheExpiration converts a TTL beyond memcached's 30-day relative limit into an absolute unix time
func memcacheExpiration(ttl int64) int32 {
if ttl > memcacheMaxRelativeTTL {
ttl += timeNow().Unix()
}
return int32(min(ttl, math.MaxInt32))
}
func (c *memcacheCache) Get(key string) (string, bool) {
item, err := c.client.Get(key)
if err != nil {
return "", false
}
return string(item.Value), true
}
func (c *memcacheCache) Put(key, value string, ttl int64) error {
return c.client.Set(&memcache.Item{Key: key, Value: []byte(value), Expiration: memcacheExpiration(ttl)})
}
func (c *memcacheCache) Delete(key string) error {
if err := c.client.Delete(key); err != nil && !errors.Is(err, memcache.ErrCacheMiss) {
return err
}
return nil
}
func (c *memcacheCache) IsExist(key string) bool {
_, err := c.client.Get(key)
return err == nil
}
func (c *memcacheCache) Ping() error {
const key = "__gitea_cache_ping"
if err := c.Put(key, "ping", 10); err != nil {
return err
}
return c.Delete(key)
}