| 1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- // Copyright 2022 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package cache
-
- import (
- "context"
- "time"
- )
-
- type cacheContextKeyType struct{}
-
- var cacheContextKey = cacheContextKeyType{}
-
- // contextCacheLifetime is the max lifetime of context cache.
- // Since context cache is used to cache data in a request level context, 5 minutes is enough.
- // If a context cache is used more than 5 minutes, it's probably abused.
- const contextCacheLifetime = 5 * time.Minute
-
- func WithCacheContext(ctx context.Context) context.Context {
- if c := GetContextCache(ctx); c != nil {
- return ctx
- }
- return context.WithValue(ctx, cacheContextKey, NewEphemeralCache(contextCacheLifetime))
- }
-
- func GetContextCache(ctx context.Context) *EphemeralCache {
- c, _ := ctx.Value(cacheContextKey).(*EphemeralCache)
- return c
- }
-
- // GetWithContextCache returns the cache value of the given key in the given context.
- // FIXME: in some cases, the "context cache" should not be used, because it has uncontrollable behaviors
- // For example, these calls:
- // * GetWithContextCache(TargetID) -> OtherCodeCreateModel(TargetID) -> GetWithContextCache(TargetID)
- // Will cause the second call is not able to get the correct created target.
- // UNLESS it is certain that the target won't be changed during the request, DO NOT use it.
- func GetWithContextCache[T, K any](ctx context.Context, groupKey string, targetKey K, f func(context.Context, K) (T, error)) (T, error) {
- if c := GetContextCache(ctx); c != nil {
- return GetWithEphemeralCache(ctx, c, groupKey, targetKey, f)
- }
- return f(ctx, targetKey)
- }
|