Observe + metrics

This commit is contained in:
mr
2026-04-29 11:43:52 +02:00
parent 4484c2d5d9
commit eaa983c92e
11 changed files with 703 additions and 198 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"slices"
"sync"
"time"
oclib "cloud.o-forge.io/core/oc-lib"
"cloud.o-forge.io/core/oc-lib/config"
@@ -19,14 +20,15 @@ var ressourceCols = []oclib.LibDataEnum{
var SearchMu sync.RWMutex
var SearchStreamAction = map[string][]*peer.Peer{}
var SearchStream = map[string]chan *peer.Peer{}
var SearchStream = map[string]chan WSMessage{}
func EmitNATS(user string, groups []string, message tools.PropalgationMessage) {
b, _ := json.Marshal(message)
if message.Action == tools.PB_SEARCH {
SearchMu.Lock()
SearchStream[user] = make(chan *peer.Peer, 128)
SearchStream[user] = make(chan WSMessage, 128)
SearchStreamAction[user] = []*peer.Peer{}
fmt.Println("NEW PB")
SearchMu.Unlock()
}
tools.NewNATSCaller().SetNATSPub(tools.PROPALGATION_EVENT, tools.NATSResponse{
@@ -39,24 +41,6 @@ func EmitNATS(user string, groups []string, message tools.PropalgationMessage) {
})
}
// un ressource quand on l'ajoute à notre catalogue elle nous est étrangère.
// pour se la réaffecté à soit, on peut alors changer le créator ID.
// pour protéger une ressource l'idée serait de la signée.
// si on la stocke en base, elle va se dépréciée plus encore si le user n'est pas un partenaire.
// elle ne sera pas maintenue à jour. Si c'est une ressource publique et qu'elle change
// l'offre peut disparaitre mais subsisté chez nous.
// alors si on en dispose et qu'on souhaite l'exploité. On doit en vérifier la validité... ou...
// la mettre à jour. Le problème de la mise à jour c'est qu'on peut facilement
// overflow.... de stream pour avoir à jour sa ressource.
// donc l'idée est que la vérification soit manuelle... ou lors d'une vérification de dernière instance.
// si une ressource est exploitée dans un workflow ou un shared workspace.
// elle doit être vérifié par les pairs engagés.
// si la donnée est déclaré comme donnée de l'emmetteur alors on vérifie que la signature est bien émise, par
// l'emmetteur. Sinon... on doit interrogé le pair qui a émit la donnée. Est ce que la donnée est à jour.
// lui va vérifier la signature de la ressource qu'il possède correspondante si elle existe, si non. AIE,
// on met à jour mais on pète une erreur.
var self *peer.Peer
func ListenNATS() {
@@ -65,15 +49,15 @@ func ListenNATS() {
if resp.FromApp == config.GetAppName() || !slices.Contains(ressourceCols, oclib.LibDataEnum(resp.Datatype)) {
return
}
self, _ := oclib.GetMySelf()
if self != nil && self.IsNano {
return
}
p := &peer.Peer{}
if err := json.Unmarshal(resp.Payload, &p); err == nil {
/*if err := verify(resp.Payload); err != nil {
return // don't trust anyone... only friends and foes are privilege
}*/
fmt.Println("CREATE_RESOURCE", p.GetID())
if ok, _ := oclib.IsMySelf(p.GetID()); ok {
if self.GetID() == p.GetID() {
fmt.Println("it's ourselve !")
return
}
@@ -99,11 +83,24 @@ func ListenNATS() {
"relation": p.Relation,
}, p.GetID())
}
} else if p.Relation == peer.PENDING_NANO || p.Relation == peer.NANO {
if data.ToPeer().Verify {
access.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.MASTER,
}, p.GetID())
} else {
access.UpdateOne(map[string]interface{}{
"verify": true,
"relation": peer.PENDING_MASTER,
}, p.GetID())
}
} else if p.Relation != peer.SELF && p.Relation != peer.BLACKLIST {
if p.Relation == peer.PARTNER || p.Relation == peer.PENDING_PARTNER {
p.Verify = true
p.Relation = peer.PENDING_PARTNER
}
p.IsNano = config.GetConfig().IsNano
access.StoreOne(p.Serialize(p))
}
}
@@ -113,23 +110,54 @@ func ListenNATS() {
return
}
p := &peer.Peer{}
err := json.Unmarshal(resp.Payload, p)
if err == nil {
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
fmt.Println("ADD in SEARCH STREAM", p.GetID())
if s := access.Search(&dbs.Filters{
And: map[string][]dbs.Filter{
"peer_id": {{Operator: dbs.EQUAL.String(), Value: p.PeerID}},
},
}, "", false, 0, 1); len(s.Data) > 0 {
p.Relation = s.Data[0].(*peer.Peer).Relation
} else {
p.NotInCatalog = true
}
SearchMu.Lock()
SearchStream[resp.User] <- p // TODO when do we update it in our catalog ?
SearchMu.Unlock()
if err := json.Unmarshal(resp.Payload, p); err != nil {
return
}
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
fmt.Println("ADD in SEARCH STREAM", p.GetID())
if s := access.Search(&dbs.Filters{
And: map[string][]dbs.Filter{
"peer_id": {{Operator: dbs.EQUAL.String(), Value: p.PeerID}},
},
}, "", false, 0, 1); len(s.Data) > 0 {
p.Relation = s.Data[0].(*peer.Peer).Relation
} else {
p.NotInCatalog = true
}
// Stamp volatile online state from cache.
p.Online = IsOnline(p.PeerID)
now := time.Now()
if p.Online {
p.LastHeartbeat = &now
}
SearchMu.RLock()
if ch, ok := SearchStream[resp.User]; ok {
select {
case ch <- WSMessage{Type: "peer", Peer: p}:
default:
}
}
SearchMu.RUnlock()
},
// PEER_OBSERVE_RESPONSE_EVENT is emitted by oc-discovery when it
// receives a heartbeat from an observed remote peer.
tools.PEER_OBSERVE_RESPONSE_EVENT: func(resp tools.NATSResponse) {
var batch struct {
PeerIDs []string `json:"peer_ids"`
Metrics map[string]*PeerConnectivityMetrics `json:"metrics"`
}
if err := json.Unmarshal(resp.Payload, &batch); err != nil {
return
}
if len(batch.PeerIDs) == 0 {
return
}
fmt.Println("METRICS", batch.Metrics)
HandleHeartbeatBatch(batch.PeerIDs, batch.Metrics)
},
})
}