Skip to content

Commit

Permalink
Move all env var parsing into NewCacheConfigFromEnv. Clean up names a…
Browse files Browse the repository at this point in the history
…nd add caching behavior config.
  • Loading branch information
ggreer committed Nov 7, 2024
1 parent 58bbf67 commit e62e9ad
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 52 deletions.
8 changes: 4 additions & 4 deletions pkg/uhttp/dbcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,16 @@ func NewDBCache(ctx context.Context, cfg CacheConfig) (*DBCache, error) {
return nil, err
}

if cfg.CacheTTL <= 0 {
if cfg.TTL <= 0 {
l.Debug("Cache TTL is 0. Disabling cache.")
return nil, nil
}

if cfg.CacheTTL > cacheTTLThreshold {
dc.waitDuration = time.Duration(cfg.CacheTTL*cacheTTLMultiplier) * time.Second // set as a fraction of the Cache TTL
if cfg.TTL > cacheTTLThreshold {
dc.waitDuration = time.Duration(cfg.TTL*cacheTTLMultiplier) * time.Second // set as a fraction of the Cache TTL
}

dc.expirationTime = time.Duration(cfg.CacheTTL) * time.Second // time for removing expired key
dc.expirationTime = time.Duration(cfg.TTL) * time.Second // time for removing expired key

go func(waitDuration, expirationTime time.Duration) {
ctxWithTimeout, cancel := context.WithTimeout(
Expand Down
2 changes: 1 addition & 1 deletion pkg/uhttp/dbcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestDBCache(t *testing.T) {

func getDBCacheForTesting() (*DBCache, error) {
fc, err := NewDBCache(ctx, CacheConfig{
CacheTTL: 3600,
TTL: 3600,
})
if err != nil {
return nil, err
Expand Down
114 changes: 73 additions & 41 deletions pkg/uhttp/gocache.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,29 @@ const (
defaultCacheSize = 50 // MB
)

type CacheBehavior string

const (
CacheBehaviorDefault CacheBehavior = "default"
CacheBehaviorSparse CacheBehavior = "sparse" // Only cache requests that have been requested more than once
)

type CacheBackend string

const (
CacheBackendDB CacheBackend = "db"
CacheBackendMemory CacheBackend = "memory"
CacheBackendNoop CacheBackend = "noop"
)

type CacheConfig struct {
LogDebug bool
CacheTTL int64 // If 0, cache is disabled
CacheMaxSize int
LogDebug bool
TTL int64 // If 0, cache is disabled
MaxSize int // MB
Behavior CacheBehavior
Backend CacheBackend
}

type ContextKey struct{}

type GoCache struct {
Expand All @@ -52,14 +70,16 @@ func (n *NoopCache) Clear(ctx context.Context) error {
}

func (cc *CacheConfig) ToString() string {
return fmt.Sprintf("CacheTTL: %d, CacheMaxSize: %d, LogDebug: %t", cc.CacheTTL, cc.CacheMaxSize, cc.LogDebug)
return fmt.Sprintf("CacheTTL: %d, CacheMaxSize: %d, LogDebug: %t Behavior: %v", cc.TTL, cc.MaxSize, cc.LogDebug, cc.Behavior)
}

func DefaultCacheConfig() CacheConfig {
return CacheConfig{
CacheTTL: cacheTTLDefault,
CacheMaxSize: defaultCacheSize,
LogDebug: false,
TTL: cacheTTLDefault,
MaxSize: defaultCacheSize,
LogDebug: false,
Behavior: CacheBehaviorDefault,
Backend: CacheBackendMemory,
}
}

Expand All @@ -68,7 +88,7 @@ func NewCacheConfigFromEnv() *CacheConfig {

cacheMaxSize, err := strconv.ParseInt(os.Getenv("BATON_HTTP_CACHE_MAX_SIZE"), 10, 64)
if err == nil {
config.CacheMaxSize = int(cacheMaxSize)
config.MaxSize = int(cacheMaxSize)
}

// read the `BATON_HTTP_CACHE_TTL` environment variable and return
Expand All @@ -77,7 +97,33 @@ func NewCacheConfigFromEnv() *CacheConfig {
// infinity.
cacheTTL, err := strconv.ParseInt(os.Getenv("BATON_HTTP_CACHE_TTL"), 10, 64)
if err == nil {
config.CacheTTL = min(cacheTTLMaximum, max(0, cacheTTL))
config.TTL = min(cacheTTLMaximum, max(0, cacheTTL))
}

cacheBackend := os.Getenv("BATON_HTTP_CACHE_BACKEND")
switch cacheBackend {
case "db":
config.Backend = CacheBackendDB
case "memory":
config.Backend = CacheBackendMemory
case "noop":
config.Backend = CacheBackendNoop
}

cacheBehavior := os.Getenv("BATON_HTTP_CACHE_BEHAVIOR")
switch cacheBehavior {
case "sparse":
config.Behavior = CacheBehaviorSparse
case "default":
config.Behavior = CacheBehaviorDefault
}

disableCache, err := strconv.ParseBool(os.Getenv("BATON_DISABLE_HTTP_CACHE"))
if err != nil {
disableCache = false
}
if disableCache {
config.Backend = CacheBackendNoop
}

return &config
Expand All @@ -98,68 +144,54 @@ func NewCacheConfigFromCtx(ctx context.Context) (*CacheConfig, error) {
func NewHttpCache(ctx context.Context, config *CacheConfig) (icache, error) {
l := ctxzap.Extract(ctx)

var cache icache = &NoopCache{}

if config == nil {
config = NewCacheConfigFromEnv()
}

if config.CacheTTL <= 0 {
l.Debug("CacheTTL is <=0, disabling cache.", zap.Int64("CacheTTL", config.CacheTTL))
return cache, nil
if config.TTL <= 0 {
l.Debug("CacheTTL is <=0, disabling cache.", zap.Int64("CacheTTL", config.TTL))
return NewNoopCache(ctx), nil
}

disableCache, err := strconv.ParseBool(os.Getenv("BATON_DISABLE_HTTP_CACHE"))
if err != nil {
disableCache = false
}
if disableCache {
l.Debug("BATON_DISABLE_HTTP_CACHE set, disabling cache.")
return cache, nil
}

cacheBackend := os.Getenv("BATON_HTTP_CACHE_BACKEND")
if cacheBackend == "" {
l.Debug("defaulting to db-cache")
cacheBackend = "db"
}

switch cacheBackend {
case "memory":
switch config.Backend {
case CacheBackendNoop:
l.Debug("Using noop cache")
return NewNoopCache(ctx), nil
case CacheBackendMemory:
l.Debug("Using in-memory cache")
memCache, err := NewGoCache(ctx, *config)
if err != nil {
l.Error("error creating http cache (in-memory)", zap.Error(err))
l.Error("error creating http cache (in-memory)", zap.Error(err), zap.Any("config", *config))
return nil, err
}
cache = memCache
case "db":
return memCache, nil
case CacheBackendDB:
l.Debug("Using db cache")
dbCache, err := NewDBCache(ctx, *config)
if err != nil {
l.Error("error creating http cache (db-cache)", zap.Error(err))
l.Error("error creating http cache (db-cache)", zap.Error(err), zap.Any("config", *config))
return nil, err
}
cache = dbCache
return dbCache, nil
}

return cache, nil
return NewNoopCache(ctx), nil
}

func NewGoCache(ctx context.Context, cfg CacheConfig) (*GoCache, error) {
l := ctxzap.Extract(ctx)
gc := GoCache{}
config := bigCache.DefaultConfig(time.Duration(cfg.CacheTTL) * time.Second)
config := bigCache.DefaultConfig(time.Duration(cfg.TTL) * time.Second)
config.Verbose = cfg.LogDebug
config.Shards = 4
config.HardMaxCacheSize = cfg.CacheMaxSize // value in MB, 0 value means no size limit
config.HardMaxCacheSize = cfg.MaxSize // value in MB, 0 value means no size limit
cache, err := bigCache.New(ctx, config)
if err != nil {
l.Error("http cache initialization error", zap.Error(err))
l.Error("bigcache initialization error", zap.Error(err))
return nil, err
}

l.Debug("http cache config",
l.Debug("bigcache config",
zap.Dict("config",
zap.Int("Shards", config.Shards),
zap.Duration("LifeWindow", config.LifeWindow),
Expand Down
12 changes: 6 additions & 6 deletions pkg/uhttp/wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,9 @@ func TestWrapperConfig(t *testing.T) {
url: "http://example.com",
options: nil,
cc: CacheConfig{
LogDebug: true,
CacheTTL: 1800,
CacheMaxSize: 1024,
LogDebug: true,
TTL: 1800,
MaxSize: 1024,
},
expected: expected{
method: http.MethodGet,
Expand All @@ -449,9 +449,9 @@ func TestWrapperConfig(t *testing.T) {
url: "http://example.com",
options: []RequestOption{WithJSONBody(exampleBody), WithAcceptJSONHeader()},
cc: CacheConfig{
LogDebug: true,
CacheTTL: 600,
CacheMaxSize: 0,
LogDebug: true,
TTL: 600,
MaxSize: 0,
},
expected: expected{
method: http.MethodPost,
Expand Down

0 comments on commit e62e9ad

Please sign in to comment.