diff --git a/dbm/json_data.go b/dbm/json_data.go index 8236853..9a18c08 100644 --- a/dbm/json_data.go +++ b/dbm/json_data.go @@ -67,9 +67,7 @@ func (d *DBMHandler) Delete(c *gin.Context) { } response := json_data.NewResponse() - if payload.Set != nil { - response.Set, err = d.DBM.RemoveDatapoint(payload.Set...) if err != nil { r := json_data.NewResponse() diff --git a/dbm/subscribe.go b/dbm/subscribe.go index c8fe6b8..f4c8d99 100644 --- a/dbm/subscribe.go +++ b/dbm/subscribe.go @@ -49,6 +49,7 @@ func (d *DBMHandler) Subscribe(req *json_dataModels.Request, id string) { Path: dp.Path, Value: dp.Value, HasChild: dp.Datapoints != nil, + Rights: dp.ReadWrite.GetRights(), Driver: sub.Driver, Drivers: &dp.Drivers, }) diff --git a/go.mod b/go.mod index 245f521..a9bd3bb 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/tecamino/tecamino-json_data v0.0.17 + github.com/tecamino/tecamino-json_data v0.0.19 github.com/tecamino/tecamino-logger v0.2.0 ) diff --git a/go.sum b/go.sum index 724a280..781185a 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tecamino/tecamino-json_data v0.0.17 h1:M12UzKbfIgu/q3ERsEhGNDV3DYOvc0TioU288kQjDCA= -github.com/tecamino/tecamino-json_data v0.0.17/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= +github.com/tecamino/tecamino-json_data v0.0.19 h1:jaEiY38Rdur1ZKJ5/5H/7ZL5vn1NdUnM/0bQj2vByKc= +github.com/tecamino/tecamino-json_data v0.0.19/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU= github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/models/datapoint.go b/models/datapoint.go index d114fc9..1f65b40 100644 --- a/models/datapoint.go +++ b/models/datapoint.go @@ -55,8 +55,8 @@ func (d *Datapoint) Set(path string, set json_dataModels.Set) (bool, error) { changed = true d.Value = d.Type.ConvertValue(set.Value) } - } + if set.Rights != "" { changed = true d.ReadWrite = set.Rights.GetRights() @@ -108,7 +108,8 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso if i == len(parts)-1 { // Leaf node: create or update datapoint if existing, ok := current.Datapoints[part]; ok { - publish, err := existing.Set("", dp) + + _, err := existing.Set("", dp) if err != nil { return nil, nil, err } @@ -122,18 +123,18 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso Updated: true, }) - if publish { - existing.Publish(OnChange) - } + existing.Publish(OnChange) + } else { ndp := Datapoint{ Uuid: uuid.New(), CreateDateTime: time.Now().UnixMilli(), Subscriptions: InitSubscribtion(), } + // Create new current.Datapoints[part] = &ndp - publish, err := ndp.Set(strings.Join(parts, ":"), dp) + _, err := ndp.Set(strings.Join(parts, ":"), dp) if err != nil { return nil, nil, err } @@ -145,10 +146,9 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso Rights: ndp.ReadWrite, Driver: dp.Driver, }) - if publish { - current.Publish(OnChange) - } - //add uuid to flat map for faster lookuo + ndp.Publish(OnCreate) + + //add uuid to flat map for faster lookup uuids[ndp.Uuid] = &ndp } } @@ -178,6 +178,8 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso newDp.ReadWrite = dp.Rights.GetRights() } + newDp.Publish(OnCreate) + current.Datapoints[part] = newDp current = newDp @@ -214,7 +216,7 @@ func (d *Datapoint) ImportDatapoint(dp *Datapoint, path string) (uuids Uuids, er dp.UpdateDateTime = time.Now().UnixMilli() dp.Subscriptions = InitSubscribtion() current.Datapoints[part] = dp - //add uuid to flat map for faster lookuo + //add uuid to flat map for faster lookup uuids[dp.Uuid] = dp dp.Publish(OnChange) } @@ -270,47 +272,64 @@ func (d *Datapoint) UpdateValue(conns *ws.ClientHandler, value any) error { return nil } -func (d *Datapoint) RemoveDatapoint(conns *ws.ClientHandler, set json_dataModels.Set) (json_dataModels.Set, error) { +func (d *Datapoint) RemoveDatapoint(conns *ws.ClientHandler, set json_dataModels.Set) (sets []json_dataModels.Set, err error) { parts := strings.Split(set.Path, ":") if len(parts) < 1 { - return json_dataModels.Set{}, fmt.Errorf("invalid path: '%s'", set.Path) + return sets, fmt.Errorf("invalid path: '%s'", set.Path) } current := d for i := 0; i < len(parts)-1; i++ { next, ok := current.Datapoints[parts[i]] if !ok { - return json_dataModels.Set{}, fmt.Errorf("path not found: '%s'", strings.Join(parts[:i+1], ":")) + return sets, fmt.Errorf("path not found: '%s'", strings.Join(parts[:i+1], ":")) } current = next } toDelete := parts[len(parts)-1] if dp, ok := current.Datapoints[toDelete]; ok { + sets = append(sets, removeChildren(dp)...) dp.Publish(OnDelete) + sets = append(sets, json_dataModels.Set{ + Uuid: dp.Uuid, + Path: dp.Path, + }) delete(current.Datapoints, toDelete) - return json_dataModels.Set{ - Uuid: set.Uuid, - Path: set.Path, - }, nil + return sets, nil } - return json_dataModels.Set{}, fmt.Errorf("datapoint '%s' not found", set.Path) + return sets, fmt.Errorf("datapoint '%s' not found", set.Path) +} + +// removes all children and grandchlidren of datapoint +func removeChildren(dp *Datapoint) (sets []json_dataModels.Set) { + for name, d := range dp.Datapoints { + sets = append(sets, removeChildren(d)...) + d.Publish(OnDelete) + sets = append(sets, json_dataModels.Set{ + Uuid: d.Uuid, + Path: d.Path, + }) + delete(d.Datapoints, name) + } + return sets } func (d *Datapoint) GetAllDatapoints(depth uint) (dps Datapoints) { var dfs func(dp *Datapoint, currentDepth uint) dfs = func(dp *Datapoint, currentDepth uint) { - if depth == 1 { - return - } else if depth == 0 { + switch depth { + case 0: // Return all descendants for _, child := range dp.Datapoints { dps = append(dps, child) dfs(child, currentDepth+1) } return + case 1: + return } if currentDepth == depth-1 { @@ -379,22 +398,26 @@ func (d *Datapoint) RemoveSubscribtion(client *wsModels.Client) { } func (d *Datapoint) Publish(eventType string) error { - for client := range d.Subscriptions { - r := json_data.NewResponse() - r.AddPublish(json_dataModels.Publish{ - Event: eventType, - Uuid: d.Uuid, - Path: d.Path, - Type: d.Type, - Value: d.Value, - }) + r := json_data.NewResponse() + r.AddPublish(json_dataModels.Publish{ + Event: eventType, + Uuid: d.Uuid, + Path: d.Path, + Type: d.Type, + Value: d.Value, + }) - b, err := json.Marshal(r) - if err != nil { - return err + b, err := json.Marshal(r) + if err != nil { + return err + } + switch eventType { + case OnCreate, OnDelete: + ws.SendBroadcast(b) + default: + for client := range d.Subscriptions { + client.SendResponse(b) } - - client.SendResponse(b) } return nil } diff --git a/models/dbm.go b/models/dbm.go index 716f90f..2bc4a9d 100644 --- a/models/dbm.go +++ b/models/dbm.go @@ -87,18 +87,20 @@ func (d *DBM) UpdateDatapointValue(value any, uid uuid.UUID, path ...string) err return d.Datapoints.UpdateDatapointValue(value, path[0]) } -func (d *DBM) RemoveDatapoint(sets ...json_dataModels.Set) ([]json_dataModels.Set, error) { - var lsRemoved []json_dataModels.Set +func (d *DBM) RemoveDatapoint(sets ...json_dataModels.Set) (lsRemoved []json_dataModels.Set, err error) { for _, set := range sets { - removed, err := d.Datapoints.RemoveDatapoint(d.Conns, set) - if err != nil { - return lsRemoved, err + if set.Path == "" { + if dp, ok := d.Uuids[set.Uuid]; ok { + set.Path = dp.Path + } } - lsRemoved = append(lsRemoved, removed) - d.ModifyCountedDatapoints(1, true) + lsRemoved, err = d.Datapoints.RemoveDatapoint(d.Conns, set) + if err != nil { + return + } + d.ModifyCountedDatapoints(uint64(len(lsRemoved)), true) } - - return lsRemoved, nil + return } func (d *DBM) QueryDatapoints(depth uint, uid uuid.UUID, key ...string) []*Datapoint { @@ -159,8 +161,6 @@ func (d *DBM) GoSystemTime() error { func (d *DBM) GoSystemMemory() error { path := "System:UsedMemory" - var m runtime.MemStats - var mOld uint64 typ := json_dataModels.STR rights := json_dataModels.Read @@ -172,13 +172,11 @@ func (d *DBM) GoSystemMemory() error { go func() { for { + var m runtime.MemStats runtime.ReadMemStats(&m) - if m.Sys != mOld { - mem := fmt.Sprintf("%.2f MB", float64(m.Sys)/1024/1024) - if er := d.UpdateDatapointValue(mem, uuid.Nil, path); er != nil { - d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error()) - } - mOld = m.Sys + mem := fmt.Sprintf("%.2f MB", float64(m.Alloc)/1024/1024) + if er := d.UpdateDatapointValue(mem, uuid.Nil, path); er != nil { + d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error()) } time.Sleep(time.Second) }