From 294e33d1107149e04b438b1d6f22dbb99fa88d36 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 4 Nov 2025 23:03:45 +0000 Subject: [PATCH 1/3] fix: #686 - concurrent map read and write --- service/internal/entities/storage.go | 6 ++++++ service/internal/entities/templates.go | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/service/internal/entities/storage.go b/service/internal/entities/storage.go index b94ddf5..5bed05c 100644 --- a/service/internal/entities/storage.go +++ b/service/internal/entities/storage.go @@ -60,10 +60,16 @@ func GetAll() *variableBase { } func GetEntities() entitiesByClass { + rwmutex.RLock() + defer rwmutex.RUnlock() + return contents.Entities } func GetEntityInstances(entityName string) entityInstancesByKey { + rwmutex.RLock() + defer rwmutex.RUnlock() + if entities, ok := contents.Entities[entityName]; ok { return entities } diff --git a/service/internal/entities/templates.go b/service/internal/entities/templates.go index 46b5bff..ccb67f0 100644 --- a/service/internal/entities/templates.go +++ b/service/internal/entities/templates.go @@ -91,7 +91,7 @@ func ParseTemplateWithArgs(source string, ent *Entity, args map[string]string) s } templateVariables := &variableBase{ - OliveTin: contents.OliveTin, + OliveTin: GetAll().OliveTin, Arguments: args, CurrentEntity: entdata, } @@ -126,5 +126,8 @@ func ParseTemplateBoolWith(source string, ent *Entity) bool { } func ClearEntities(entityType string) { + rwmutex.Lock() + defer rwmutex.Unlock() + delete(contents.Entities, entityType) } From 2b24daa6d0f9e226ce71569e474fa72fb98600e8 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 4 Nov 2025 23:18:41 +0000 Subject: [PATCH 2/3] fix: Address concurrency issue in entities storage --- service/internal/entities/storage.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/service/internal/entities/storage.go b/service/internal/entities/storage.go index 5bed05c..55a3e36 100644 --- a/service/internal/entities/storage.go +++ b/service/internal/entities/storage.go @@ -61,9 +61,19 @@ func GetAll() *variableBase { func GetEntities() entitiesByClass { rwmutex.RLock() - defer rwmutex.RUnlock() - return contents.Entities + copiedEntities := make(entitiesByClass, len(contents.Entities)) + for entityName, entityInstances := range contents.Entities { + copiedInstances := make(entityInstancesByKey, len(entityInstances)) + for key, entity := range entityInstances { + copiedInstances[key] = entity + } + copiedEntities[entityName] = copiedInstances + } + + rwmutex.RUnlock() + + return copiedEntities } func GetEntityInstances(entityName string) entityInstancesByKey { From 055472902d9d6b71853ec4502e5a61a71f56116a Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 4 Nov 2025 23:30:14 +0000 Subject: [PATCH 3/3] fix: #686 - concurrent map read and write - in entity instances --- service/internal/entities/storage.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/service/internal/entities/storage.go b/service/internal/entities/storage.go index 55a3e36..0ac35b3 100644 --- a/service/internal/entities/storage.go +++ b/service/internal/entities/storage.go @@ -63,8 +63,10 @@ func GetEntities() entitiesByClass { rwmutex.RLock() copiedEntities := make(entitiesByClass, len(contents.Entities)) + for entityName, entityInstances := range contents.Entities { copiedInstances := make(entityInstancesByKey, len(entityInstances)) + for key, entity := range entityInstances { copiedInstances[key] = entity } @@ -81,10 +83,15 @@ func GetEntityInstances(entityName string) entityInstancesByKey { defer rwmutex.RUnlock() if entities, ok := contents.Entities[entityName]; ok { - return entities + copiedInstances := make(entityInstancesByKey, len(entities)) + + for key, entity := range entities { + copiedInstances[key] = entity + } + return copiedInstances } - return nil + return make(entityInstancesByKey, 0) } func AddEntity(entityName string, entityKey string, data any) {