Преглед изворни кода

experimenting with recursive update

reid пре 2 година
родитељ
комит
1f913efcb6
1 измењених фајлова са 24 додато и 37 уклоњено
  1. 24 37
      broadcast/broadcast.go

+ 24 - 37
broadcast/broadcast.go

@@ -246,6 +246,7 @@ func UpdateBroadcastState(values map[string]interface{}) error {
 		if err := recursiveUpdate(field, val); err != nil {
 			mu.Unlock()
 			return fmt.Errorf("error updating field %s: %v", key, err)
+			return err
 		}
 	}
 	mu.Unlock()
@@ -255,54 +256,41 @@ func UpdateBroadcastState(values map[string]interface{}) error {
 
 // this allows us to insert stuff into nested structs/keys and not overwrite the existing contents
 func recursiveUpdate(dst, src reflect.Value) error {
-    // Check if neither dst nor src are maps or structs (e.g., both are primitive types)
-    if dst.Kind() != reflect.Map && dst.Kind() != reflect.Struct &&
-       src.Kind() != reflect.Map && src.Kind() != reflect.Struct {
-        if dst.Type() != src.Type() {
-            return fmt.Errorf("type mismatch: expected %s, got %s", dst.Type(), src.Type())
-        }
-        dst.Set(src)
-        return nil
-    }
+	if !dst.CanSet() {
+		return fmt.Errorf("field (type: %s, kind: %s) is not settable", dst.Type(), dst.Kind())
+	}
 	// If dst is a struct and src is a map, handle them field by field
-	if dst.Kind() == reflect.Map && src.Kind() == reflect.Map {
-		if dst.IsNil() {
-			dst.Set(reflect.MakeMap(dst.Type()))
-		}
+	if dst.Kind() == reflect.Struct && src.Kind() == reflect.Map {
 		for _, key := range src.MapKeys() {
-			dstVal := dst.MapIndex(key)
-			// If the value in the map is a struct, create a new instance for modification
-			if dstVal.Kind() == reflect.Struct {
-				tmpVal := reflect.New(dstVal.Type()).Elem()
-				tmpVal.Set(dstVal)
-				dstVal = tmpVal
+			dstField := dst.FieldByName(key.String())
+			if !dstField.IsValid() {
+				return fmt.Errorf("field %s does not exist in the struct", key.String())
+			}
+			// Initialize the map if it's nil and we're trying to set a map
+			if dstField.Kind() == reflect.Map && dstField.IsNil() && src.MapIndex(key).Kind() == reflect.Map {
+				dstField.Set(reflect.MakeMap(dstField.Type()))
+			}
+			if !dstField.CanSet() {
+				return fmt.Errorf("field %s is not settable in the struct", key.String())
 			}
 			srcVal := src.MapIndex(key)
 			if srcVal.Kind() == reflect.Interface {
 				srcVal = srcVal.Elem()
 			}
-			if err := recursiveUpdate(dstVal, srcVal); err != nil {
+			if err := recursiveUpdate(dstField, srcVal); err != nil {
 				return err
 			}
-			// If the value in the map was a struct, update the map with the modified struct
-			if dstVal.Kind() == reflect.Struct {
-				dst.SetMapIndex(key, dstVal)
-			}
 		}
 		return nil
 	}
 	// If both dst and src are maps, handle them recursively
 	if dst.Kind() == reflect.Map && src.Kind() == reflect.Map {
-		if dst.IsNil() {
-			dst.Set(reflect.MakeMap(dst.Type()))
-		}
 		for _, key := range src.MapKeys() {
 			srcVal := src.MapIndex(key)
 			// If the key doesn't exist in dst, initialize it
 			dstVal := dst.MapIndex(key)
 			if !dstVal.IsValid() {
 				dstVal = reflect.New(dst.Type().Elem()).Elem()
-				dst.SetMapIndex(key, dstVal)  // Set the new value directly into the map
 			}
 			// Recursive call to handle potential nested maps or structs
 			if err := recursiveUpdate(dstVal, srcVal); err != nil {
@@ -390,18 +378,17 @@ func shipStatusLoop() {
 			piers := conf.Piers
 			updates, err := constructPierInfo(piers)
 			if err != nil {
-				errmsg := fmt.Sprintf("Unable to build pier info: %v",err)
+				errmsg := fmt.Sprintf("Unable to build pier info: %v", err)
 				config.Logger.Warn(errmsg)
+				continue
 			}
-			// update broadcastState
-			err = UpdateBroadcastState(map[string]interface{}{
-				"Urbits": updates,
-			})
-			if err != nil {
-				errmsg := fmt.Sprintf("Unable to update ship state: %v", err)
-				config.Logger.Error(errmsg)
+			mu.Lock()  // Locking the mutex
+			for key, urbit := range updates {
+				broadcastState.Urbits[key] = urbit
 			}
+			mu.Unlock()  // Unlocking the mutex
+			BroadcastToClients()
 			config.Logger.Info("ship bstate updated")
 		}
 	}
-}
+}