Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
17
cloud/maplefile-backend/pkg/storage/cache/twotiercache/provider.go
vendored
Normal file
17
cloud/maplefile-backend/pkg/storage/cache/twotiercache/provider.go
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package twotiercache
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/cache/cassandracache"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/memory/redis"
|
||||
)
|
||||
|
||||
// ProvideTwoTierCache provides a two-tier cache instance for Wire DI
|
||||
func ProvideTwoTierCache(
|
||||
redisCache redis.Cacher,
|
||||
cassandraCache cassandracache.CassandraCacher,
|
||||
logger *zap.Logger,
|
||||
) TwoTierCacher {
|
||||
return NewTwoTierCache(redisCache, cassandraCache, logger)
|
||||
}
|
||||
106
cloud/maplefile-backend/pkg/storage/cache/twotiercache/twotiercache.go
vendored
Normal file
106
cloud/maplefile-backend/pkg/storage/cache/twotiercache/twotiercache.go
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// monorepo/cloud/maplefileapps-backend/pkg/storage/cache/twotiercache/twotiercache.go
|
||||
package twotiercache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/cache/cassandracache"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/memory/redis"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TwoTierCacher interface {
|
||||
Shutdown(ctx context.Context)
|
||||
Get(ctx context.Context, key string) ([]byte, error)
|
||||
Set(ctx context.Context, key string, val []byte) error
|
||||
SetWithExpiry(ctx context.Context, key string, val []byte, expiry time.Duration) error
|
||||
Delete(ctx context.Context, key string) error
|
||||
PurgeExpired(ctx context.Context) error
|
||||
}
|
||||
|
||||
// twoTierCacheImpl: clean 2-layer (read-through write-through) cache
|
||||
//
|
||||
// L1: Redis (fast, in-memory)
|
||||
// L2: Cassandra (persistent)
|
||||
//
|
||||
// On Get: check Redis → then Cassandra → if found in Cassandra → populate Redis
|
||||
// On Set: write to both
|
||||
// On SetWithExpiry: write to both with expiry
|
||||
// On Delete: remove from both
|
||||
type twoTierCacheImpl struct {
|
||||
RedisCache redis.Cacher
|
||||
CassandraCache cassandracache.CassandraCacher
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewTwoTierCache(redisCache redis.Cacher, cassandraCache cassandracache.CassandraCacher, logger *zap.Logger) TwoTierCacher {
|
||||
logger = logger.Named("TwoTierCache")
|
||||
return &twoTierCacheImpl{
|
||||
RedisCache: redisCache,
|
||||
CassandraCache: cassandraCache,
|
||||
Logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) Get(ctx context.Context, key string) ([]byte, error) {
|
||||
val, err := c.RedisCache.Get(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if val != nil {
|
||||
c.Logger.Debug("cache hit from Redis", zap.String("key", key))
|
||||
return val, nil
|
||||
}
|
||||
|
||||
val, err = c.CassandraCache.Get(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if val != nil {
|
||||
c.Logger.Debug("cache hit from Cassandra, writing back to Redis", zap.String("key", key))
|
||||
_ = c.RedisCache.Set(ctx, key, val)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) Set(ctx context.Context, key string, val []byte) error {
|
||||
if err := c.RedisCache.Set(ctx, key, val); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.CassandraCache.Set(ctx, key, val); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) SetWithExpiry(ctx context.Context, key string, val []byte, expiry time.Duration) error {
|
||||
if err := c.RedisCache.SetWithExpiry(ctx, key, val, expiry); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.CassandraCache.SetWithExpiry(ctx, key, val, expiry); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) Delete(ctx context.Context, key string) error {
|
||||
if err := c.RedisCache.Delete(ctx, key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.CassandraCache.Delete(ctx, key); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) PurgeExpired(ctx context.Context) error {
|
||||
return c.CassandraCache.PurgeExpired(ctx)
|
||||
}
|
||||
|
||||
func (c *twoTierCacheImpl) Shutdown(ctx context.Context) {
|
||||
c.Logger.Info("two-tier cache shutting down...")
|
||||
c.RedisCache.Shutdown(ctx)
|
||||
c.CassandraCache.Shutdown()
|
||||
c.Logger.Info("two-tier cache shutdown complete")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue