gitea源码

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package cache
  4. import (
  5. "context"
  6. "time"
  7. )
  8. type cacheContextKeyType struct{}
  9. var cacheContextKey = cacheContextKeyType{}
  10. // contextCacheLifetime is the max lifetime of context cache.
  11. // Since context cache is used to cache data in a request level context, 5 minutes is enough.
  12. // If a context cache is used more than 5 minutes, it's probably abused.
  13. const contextCacheLifetime = 5 * time.Minute
  14. func WithCacheContext(ctx context.Context) context.Context {
  15. if c := GetContextCache(ctx); c != nil {
  16. return ctx
  17. }
  18. return context.WithValue(ctx, cacheContextKey, NewEphemeralCache(contextCacheLifetime))
  19. }
  20. func GetContextCache(ctx context.Context) *EphemeralCache {
  21. c, _ := ctx.Value(cacheContextKey).(*EphemeralCache)
  22. return c
  23. }
  24. // GetWithContextCache returns the cache value of the given key in the given context.
  25. // FIXME: in some cases, the "context cache" should not be used, because it has uncontrollable behaviors
  26. // For example, these calls:
  27. // * GetWithContextCache(TargetID) -> OtherCodeCreateModel(TargetID) -> GetWithContextCache(TargetID)
  28. // Will cause the second call is not able to get the correct created target.
  29. // UNLESS it is certain that the target won't be changed during the request, DO NOT use it.
  30. func GetWithContextCache[T, K any](ctx context.Context, groupKey string, targetKey K, f func(context.Context, K) (T, error)) (T, error) {
  31. if c := GetContextCache(ctx); c != nil {
  32. return GetWithEphemeralCache(ctx, c, groupKey, targetKey, f)
  33. }
  34. return f(ctx, targetKey)
  35. }