Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,108 @@
// monorepo/cloud/maplefileapps-backend/pkg/storage/cache/cassandracache/cassandaracache.go
package cassandracache
import (
"context"
"time"
"github.com/gocql/gocql"
"go.uber.org/zap"
)
type CassandraCacher interface {
Shutdown()
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
}
type cache struct {
Session *gocql.Session
Logger *zap.Logger
}
func NewCassandraCacher(session *gocql.Session, logger *zap.Logger) CassandraCacher {
logger = logger.Named("CassandraCache")
logger.Info("cassandra cache initialized")
return &cache{
Session: session,
Logger: logger,
}
}
func (s *cache) Shutdown() {
s.Logger.Info("cassandra cache shutting down...")
s.Session.Close()
}
func (s *cache) Get(ctx context.Context, key string) ([]byte, error) {
var value []byte
var expiresAt time.Time
query := `SELECT value, expires_at FROM pkg_cache_by_key_with_asc_expire_at WHERE key=?`
err := s.Session.Query(query, key).WithContext(ctx).Consistency(gocql.LocalQuorum).Scan(&value, &expiresAt)
if err == gocql.ErrNotFound {
return nil, nil
}
if err != nil {
return nil, err
}
// Check if expired in application code
if time.Now().After(expiresAt) {
// Entry is expired, delete it and return nil
_ = s.Delete(ctx, key) // Clean up expired entry
return nil, nil
}
return value, nil
}
func (s *cache) Set(ctx context.Context, key string, val []byte) error {
expiresAt := time.Now().Add(24 * time.Hour) // Default 24 hour expiry
return s.Session.Query(`INSERT INTO pkg_cache_by_key_with_asc_expire_at (key, expires_at, value) VALUES (?, ?, ?)`,
key, expiresAt, val).WithContext(ctx).Consistency(gocql.LocalQuorum).Exec()
}
func (s *cache) SetWithExpiry(ctx context.Context, key string, val []byte, expiry time.Duration) error {
expiresAt := time.Now().Add(expiry)
return s.Session.Query(`INSERT INTO pkg_cache_by_key_with_asc_expire_at (key, expires_at, value) VALUES (?, ?, ?)`,
key, expiresAt, val).WithContext(ctx).Consistency(gocql.LocalQuorum).Exec()
}
func (s *cache) Delete(ctx context.Context, key string) error {
return s.Session.Query(`DELETE FROM pkg_cache_by_key_with_asc_expire_at WHERE key=?`,
key).WithContext(ctx).Consistency(gocql.LocalQuorum).Exec()
}
func (s *cache) PurgeExpired(ctx context.Context) error {
now := time.Now()
// Thanks to the index on expires_at, this query is efficient
iter := s.Session.Query(`SELECT key FROM pkg_cache_by_key_with_asc_expire_at WHERE expires_at < ? ALLOW FILTERING`,
now).WithContext(ctx).Iter()
var expiredKeys []string
var key string
for iter.Scan(&key) {
expiredKeys = append(expiredKeys, key)
}
if err := iter.Close(); err != nil {
return err
}
// Delete expired keys in batch
if len(expiredKeys) > 0 {
batch := s.Session.NewBatch(gocql.LoggedBatch).WithContext(ctx)
for _, expiredKey := range expiredKeys {
batch.Query(`DELETE FROM pkg_cache_by_key_with_asc_expire_at WHERE key=?`, expiredKey)
}
return s.Session.ExecuteBatch(batch)
}
return nil
}

View file

@ -0,0 +1,11 @@
package cassandracache
import (
"github.com/gocql/gocql"
"go.uber.org/zap"
)
// ProvideCassandraCacher provides a Cassandra cache instance for Wire DI
func ProvideCassandraCacher(session *gocql.Session, logger *zap.Logger) CassandraCacher {
return NewCassandraCacher(session, logger)
}

View 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)
}

View 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")
}