Prepull for pod & Asym Jobs
This commit is contained in:
100
workflow_builder/considers_cache.go
Normal file
100
workflow_builder/considers_cache.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package workflow_builder
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"cloud.o-forge.io/core/oc-lib/logs"
|
||||
"cloud.o-forge.io/core/oc-lib/tools"
|
||||
)
|
||||
|
||||
// considersCache stocke les canaux en attente d'un PB_CONSIDERS,
|
||||
// indexés par "executionsId:dataType". Un même message NATS réveille
|
||||
// tous les waiters enregistrés sous la même clé (broadcast).
|
||||
type considersCache struct {
|
||||
mu sync.Mutex
|
||||
pending map[string][]chan struct{}
|
||||
}
|
||||
|
||||
var globalConsidersCache = &considersCache{
|
||||
pending: make(map[string][]chan struct{}),
|
||||
}
|
||||
|
||||
// considersKey construit la clé du cache à partir de l'ID d'exécution,
|
||||
// du type de données et du peer compute (SourcePeerID).
|
||||
// peerID permet de différencier plusieurs waiters COMPUTE_RESOURCE du même
|
||||
// executionsId (1 local + N distants en parallèle).
|
||||
func considersKey(executionsId string, dataType tools.DataType, peerID string) string {
|
||||
key := executionsId + ":" + strconv.Itoa(dataType.EnumIndex())
|
||||
if peerID != "" {
|
||||
key += ":" + peerID
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// register inscrit un nouveau canal d'attente pour la clé donnée.
|
||||
// Retourne le canal à lire et une fonction de désinscription à appeler en defer.
|
||||
func (c *considersCache) register(key string) (<-chan struct{}, func()) {
|
||||
ch := make(chan struct{}, 1)
|
||||
c.mu.Lock()
|
||||
c.pending[key] = append(c.pending[key], ch)
|
||||
c.mu.Unlock()
|
||||
|
||||
unregister := func() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
list := c.pending[key]
|
||||
for i, existing := range list {
|
||||
if existing == ch {
|
||||
c.pending[key] = append(list[:i], list[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(c.pending[key]) == 0 {
|
||||
delete(c.pending, key)
|
||||
}
|
||||
}
|
||||
return ch, unregister
|
||||
}
|
||||
|
||||
// confirm réveille tous les waiters enregistrés sous la clé donnée
|
||||
// et les supprime du cache.
|
||||
func (c *considersCache) confirm(key string) {
|
||||
c.mu.Lock()
|
||||
list := c.pending[key]
|
||||
delete(c.pending, key)
|
||||
c.mu.Unlock()
|
||||
|
||||
for _, ch := range list {
|
||||
select {
|
||||
case ch <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StartConsidersListener démarre un abonné NATS global via ListenNats (oclib)
|
||||
// qui reçoit les messages CONSIDERS_EVENT et réveille les goroutines en attente
|
||||
// via globalConsidersCache. Doit être appelé une seule fois au démarrage.
|
||||
func StartConsidersListener() {
|
||||
log := logs.GetLogger()
|
||||
log.Info().Msg("Considers NATS listener starting on " + tools.CONSIDERS_EVENT.GenerateKey())
|
||||
go tools.NewNATSCaller().ListenNats(map[tools.NATSMethod]func(tools.NATSResponse){
|
||||
tools.CONSIDERS_EVENT: func(resp tools.NATSResponse) {
|
||||
fmt.Println("CONSIDERS")
|
||||
var body struct {
|
||||
ExecutionsID string `json:"executions_id"`
|
||||
PeerID string `json:"peer_id,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(resp.Payload, &body); err != nil {
|
||||
log.Error().Msg("CONSIDERS_EVENT: cannot unmarshal payload: " + err.Error())
|
||||
return
|
||||
}
|
||||
key := considersKey(body.ExecutionsID, resp.Datatype, body.PeerID)
|
||||
log.Info().Msg(fmt.Sprintf("CONSIDERS_EVENT dispatched for key=%s", key))
|
||||
globalConsidersCache.confirm(key)
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user