- Implemented new gRPC service `AIService` in `proto/ai/v1/ai.proto` for handling natural language queries. - Generated Go code for the gRPC service and messages in `gen/ai/v1/`. - Created `services/ai-gateway/` directory structure with necessary files for the service. - Added configuration loading and structured logging. - Implemented domain logic for intent parsing and interaction with Home Assistant. - Established outbound adapters for Ollama and Home Assistant with mTLS support. - Updated `go.work` to include the new service and maintain existing dependencies. - Modified `discord-bot` to use the new `ai-gateway` for AI interactions. - Added deployment manifest for Kubernetes and CI/CD configuration for building and deploying the service.
50 lines
1.3 KiB
Go
50 lines
1.3 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
|
|
"gitea.nik4nao.com/nik/home-services/ai-gateway/internal/core/ports/driven"
|
|
)
|
|
|
|
// LightCache keeps recently-fetched light discovery data in memory.
|
|
type LightCache struct {
|
|
ttl time.Duration
|
|
loadFunc func(context.Context) ([]driven.Light, error)
|
|
|
|
mu sync.RWMutex
|
|
lights []driven.Light
|
|
loadedAt time.Time
|
|
}
|
|
|
|
// NewLightCache constructs a TTL-based in-memory light cache.
|
|
func NewLightCache(ttl time.Duration, loadFunc func(context.Context) ([]driven.Light, error)) *LightCache {
|
|
return &LightCache{ttl: ttl, loadFunc: loadFunc}
|
|
}
|
|
|
|
// Get returns the cached lights, refreshing lazily when empty or stale.
|
|
func (c *LightCache) Get(ctx context.Context) ([]driven.Light, error) {
|
|
c.mu.RLock()
|
|
if len(c.lights) > 0 && time.Since(c.loadedAt) < c.ttl {
|
|
lights := append([]driven.Light(nil), c.lights...)
|
|
c.mu.RUnlock()
|
|
return lights, nil
|
|
}
|
|
c.mu.RUnlock()
|
|
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
if len(c.lights) > 0 && time.Since(c.loadedAt) < c.ttl {
|
|
return append([]driven.Light(nil), c.lights...), nil
|
|
}
|
|
|
|
lights, err := c.loadFunc(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.lights = append([]driven.Light(nil), lights...)
|
|
c.loadedAt = time.Now()
|
|
return append([]driven.Light(nil), c.lights...), nil
|
|
}
|