feat: wire context store scaffolding and dht test skeleton
This commit is contained in:
@@ -64,6 +64,7 @@ type SLURP struct {
|
||||
dht dht.DHT
|
||||
crypto *crypto.AgeCrypto
|
||||
election *election.ElectionManager
|
||||
nodeID string
|
||||
|
||||
// Roadmap: SEC-SLURP 1.1 persistent storage wiring
|
||||
storagePath string
|
||||
@@ -85,9 +86,15 @@ type SLURP struct {
|
||||
currentAdmin string
|
||||
|
||||
// SEC-SLURP 1.1: lightweight in-memory context persistence
|
||||
contextsMu sync.RWMutex
|
||||
contextStore map[string]*slurpContext.ContextNode
|
||||
resolvedCache map[string]*slurpContext.ResolvedContext
|
||||
contextsMu sync.RWMutex
|
||||
contextCache map[string]*slurpContext.ContextNode
|
||||
resolvedCache map[string]*slurpContext.ResolvedContext
|
||||
contextBackend storage.ContextStore
|
||||
distributedStorage storage.DistributedStorage
|
||||
cacheManager storage.CacheManager
|
||||
indexManager storage.IndexManager
|
||||
backupManager storage.BackupManager
|
||||
eventNotifier storage.EventNotifier
|
||||
|
||||
// Background processing
|
||||
ctx context.Context
|
||||
@@ -382,16 +389,22 @@ func NewSLURP(
|
||||
|
||||
storagePath := defaultStoragePath(config)
|
||||
|
||||
nodeID := config.Agent.ID
|
||||
if nodeID == "" {
|
||||
nodeID = fmt.Sprintf("slurp-node-%d", time.Now().UnixNano())
|
||||
}
|
||||
|
||||
slurp := &SLURP{
|
||||
config: config,
|
||||
dht: dhtInstance,
|
||||
crypto: cryptoInstance,
|
||||
election: electionManager,
|
||||
nodeID: nodeID,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
metrics: &SLURPMetrics{LastUpdated: time.Now()},
|
||||
eventHandlers: make(map[EventType][]EventHandler),
|
||||
contextStore: make(map[string]*slurpContext.ContextNode),
|
||||
contextCache: make(map[string]*slurpContext.ContextNode),
|
||||
resolvedCache: make(map[string]*slurpContext.ResolvedContext),
|
||||
storagePath: storagePath,
|
||||
}
|
||||
@@ -443,8 +456,8 @@ func (s *SLURP) Initialize(ctx context.Context) error {
|
||||
|
||||
// Initialize in-memory persistence (SEC-SLURP 1.1 bootstrap)
|
||||
s.contextsMu.Lock()
|
||||
if s.contextStore == nil {
|
||||
s.contextStore = make(map[string]*slurpContext.ContextNode)
|
||||
if s.contextCache == nil {
|
||||
s.contextCache = make(map[string]*slurpContext.ContextNode)
|
||||
}
|
||||
if s.resolvedCache == nil {
|
||||
s.resolvedCache = make(map[string]*slurpContext.ResolvedContext)
|
||||
@@ -561,7 +574,7 @@ func (s *SLURP) Resolve(ctx context.Context, ucxlAddress string) (*ResolvedConte
|
||||
|
||||
built := buildResolvedContext(node)
|
||||
s.contextsMu.Lock()
|
||||
s.contextStore[key] = node
|
||||
s.contextCache[key] = node
|
||||
s.resolvedCache[key] = built
|
||||
s.contextsMu.Unlock()
|
||||
|
||||
@@ -726,7 +739,7 @@ func (s *SLURP) UpsertContext(ctx context.Context, node *slurpContext.ContextNod
|
||||
key := clone.UCXLAddress.String()
|
||||
|
||||
s.contextsMu.Lock()
|
||||
s.contextStore[key] = clone
|
||||
s.contextCache[key] = clone
|
||||
s.resolvedCache[key] = resolved
|
||||
s.contextsMu.Unlock()
|
||||
|
||||
@@ -1136,7 +1149,7 @@ func (s *SLURP) getContextNode(key string) *slurpContext.ContextNode {
|
||||
s.contextsMu.RLock()
|
||||
defer s.contextsMu.RUnlock()
|
||||
|
||||
if node, ok := s.contextStore[key]; ok {
|
||||
if node, ok := s.contextCache[key]; ok {
|
||||
return node
|
||||
}
|
||||
return nil
|
||||
@@ -1186,6 +1199,59 @@ func (s *SLURP) setupPersistentStorage() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initializeContextStore constructs the multi-tier context store facade.
|
||||
func (s *SLURP) initializeContextStore(ctx context.Context) error {
|
||||
if s.contextBackend != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.localStorage == nil {
|
||||
return fmt.Errorf("context store requires local storage")
|
||||
}
|
||||
|
||||
if s.cacheManager == nil {
|
||||
s.cacheManager = storage.NewNoopCacheManager()
|
||||
}
|
||||
if s.indexManager == nil {
|
||||
s.indexManager = storage.NewNoopIndexManager()
|
||||
}
|
||||
if s.backupManager == nil {
|
||||
s.backupManager = storage.NewNoopBackupManager()
|
||||
}
|
||||
if s.eventNotifier == nil {
|
||||
s.eventNotifier = storage.NewNoopEventNotifier()
|
||||
}
|
||||
|
||||
var distributed storage.DistributedStorage
|
||||
if s.dht != nil {
|
||||
if s.distributedStorage == nil {
|
||||
s.distributedStorage = storage.NewDistributedStorage(s.dht, s.nodeID, nil)
|
||||
}
|
||||
distributed = s.distributedStorage
|
||||
}
|
||||
|
||||
options := storage.DefaultContextStoreOptions()
|
||||
options.CachingEnabled = false
|
||||
options.IndexingEnabled = false
|
||||
options.EncryptionEnabled = false
|
||||
options.AutoReplicate = distributed != nil
|
||||
|
||||
s.contextBackend = storage.NewContextStore(
|
||||
s.nodeID,
|
||||
s.localStorage,
|
||||
distributed,
|
||||
nil,
|
||||
s.cacheManager,
|
||||
s.indexManager,
|
||||
s.backupManager,
|
||||
s.eventNotifier,
|
||||
options,
|
||||
)
|
||||
s.temporalStore = s.contextBackend
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// initializeTemporalSystem wires the temporal graph to the DHT-backed persistence layer.
|
||||
func (s *SLURP) initializeTemporalSystem(ctx context.Context) error {
|
||||
if s.temporalGraph != nil {
|
||||
@@ -1196,8 +1262,8 @@ func (s *SLURP) initializeTemporalSystem(ctx context.Context) error {
|
||||
return fmt.Errorf("temporal persistence requires local storage")
|
||||
}
|
||||
|
||||
if s.temporalStore == nil {
|
||||
s.temporalStore = storage.NewInMemoryContextStore()
|
||||
if err := s.initializeContextStore(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := temporal.DefaultTemporalConfig()
|
||||
@@ -1285,7 +1351,7 @@ func (s *SLURP) loadPersistedContexts(ctx context.Context) error {
|
||||
|
||||
address := strings.TrimPrefix(key, contextStoragePrefix)
|
||||
nodeClone := node.Clone()
|
||||
s.contextStore[address] = nodeClone
|
||||
s.contextCache[address] = nodeClone
|
||||
s.resolvedCache[address] = buildResolvedContext(nodeClone)
|
||||
loaded++
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user