Files
moteva/server/internal/infrastructure/cache/store.go
T
root 44406b72db Initial commit: img-infinite-canvas AI design workbench MVP
Moteva-style AI design workbench replica. Home prompt creates a project;
the project page provides an infinite canvas with node drag, zoom/pan,
a design chat panel, history replay, image asset upload, and project
save/regenerate.

- Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory
  or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage;
  sky-valley/pi agent runtime adapter.
- Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n,
  shadcn/ui components, auth (OTP/Turnstile/Google/WeChat).
- Deploy: Docker Compose and k3s manifests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 23:15:37 +08:00

90 lines
1.6 KiB
Go

package cache
import (
"context"
"encoding/json"
"errors"
"sync"
"time"
)
var ErrUnsupportedDriver = errors.New("unsupported cache driver")
type Store interface {
Get(ctx context.Context, key string, target any) (bool, error)
Set(ctx context.Context, key string, value any, ttl time.Duration) error
Delete(ctx context.Context, key string) error
}
type memoryItem struct {
value []byte
expiresAt time.Time
}
type MemoryStore struct {
mu sync.RWMutex
items map[string]memoryItem
}
func NewMemoryStore() *MemoryStore {
return &MemoryStore{
items: make(map[string]memoryItem),
}
}
func (s *MemoryStore) Get(ctx context.Context, key string, target any) (bool, error) {
if err := ctx.Err(); err != nil {
return false, err
}
s.mu.RLock()
item, ok := s.items[key]
s.mu.RUnlock()
if !ok {
return false, nil
}
if !item.expiresAt.IsZero() && time.Now().After(item.expiresAt) {
s.mu.Lock()
delete(s.items, key)
s.mu.Unlock()
return false, nil
}
if err := json.Unmarshal(item.value, target); err != nil {
return false, err
}
return true, nil
}
func (s *MemoryStore) Set(ctx context.Context, key string, value any, ttl time.Duration) error {
if err := ctx.Err(); err != nil {
return err
}
data, err := json.Marshal(value)
if err != nil {
return err
}
var expiresAt time.Time
if ttl > 0 {
expiresAt = time.Now().Add(ttl)
}
s.mu.Lock()
s.items[key] = memoryItem{value: data, expiresAt: expiresAt}
s.mu.Unlock()
return nil
}
func (s *MemoryStore) Delete(ctx context.Context, key string) error {
if err := ctx.Err(); err != nil {
return err
}
s.mu.Lock()
delete(s.items, key)
s.mu.Unlock()
return nil
}