Now using a more efficient data structure in the prometheus code for saving the last state to improve efficiency and minimize copying even more.

This commit is contained in:
Erik Brakkee 2024-08-14 23:38:45 +02:00
parent ae59905329
commit c86ea894d1

View File

@ -12,10 +12,30 @@ import (
const NAMESPACE = "converge"
// more efficient state representation for state
type PrometheusState struct {
agents map[string]*models.Agent
clients map[string]*models.Client
}
func NewPrometheusState(state *models.State) *PrometheusState {
res := PrometheusState{
agents: make(map[string]*models.Agent),
clients: make(map[string]*models.Client),
}
for i, _ := range state.Agents {
res.agents[state.Agents[i].Guid] = &state.Agents[i]
}
for i, _ := range state.Clients {
res.clients[state.Clients[i].Guid] = &state.Clients[i]
}
return &res
}
var (
// remember previous values of agent guids and clients so that we can increment
// the cumulative counters.
lastState *models.State = &models.State{}
lastState *PrometheusState = NewPrometheusState(&models.State{})
cumulativeAgentCount = promauto.NewCounter(prometheus.CounterOpts{
Namespace: NAMESPACE,
@ -129,7 +149,7 @@ func clientLabels(client *models.Client) prometheus.Labels {
}
func agentActive(agent *models.Agent) {
prevAgent, ok := findAgent(lastState, agent.Guid)
prevAgent, ok := lastState.agents[agent.Guid]
if ok && *prevAgent != *agent {
removeAgentInfoMetrics(prevAgent)
}
@ -142,26 +162,8 @@ func agentActive(agent *models.Agent) {
Set(float64(time.Now().Sub(agent.StartTime).Seconds()))
}
func findAgent(state *models.State, guid string) (*models.Agent, bool) {
for i := range state.Agents {
if state.Agents[i].Guid == guid {
return &state.Agents[i], true
}
}
return nil, false
}
func findClient(state *models.State, guid string) (*models.Client, bool) {
for i := range state.Clients {
if state.Clients[i].Guid == guid {
return &state.Clients[i], true
}
}
return nil, false
}
func clientActive(client *models.Client) {
prevClient, ok := findClient(lastState, client.Guid)
prevClient, ok := lastState.clients[client.Guid]
if ok && *prevClient != *client {
removeClientInfoMetrics(prevClient)
}
@ -214,38 +216,35 @@ var prometheusChannel = make(chan func())
func updateMetrics(state *models.State) {
prometheusChannel <- func() {
updateMetricsImpl(state)
updateMetricsImpl(NewPrometheusState(state))
}
}
func updateDurations() {
for i := range lastState.Agents {
agent := &lastState.Agents[i]
for _, agent := range lastState.agents {
agentDuration.
With(prometheus.Labels{"agent_guid": agent.Guid}).
Set(float64(time.Now().Sub(agent.StartTime).Seconds()))
}
for i := range lastState.Clients {
client := &lastState.Clients[i]
for _, client := range lastState.clients {
clientDuration.
With(prometheus.Labels{"client_guid": client.Guid}).
Set(float64(time.Now().Sub(client.StartTime).Seconds()))
}
}
func updateMetricsImpl(state *models.State) {
func updateMetricsImpl(state *PrometheusState) {
agentGuids := make(map[string]*models.Agent)
clientGuids := make(map[string]*models.Client)
agentCount.Set(float64(len(state.Agents)))
agentCount.Set(float64(len(state.agents)))
disconnectedAgents := make(map[string]*models.Agent)
for i := range lastState.Agents {
agent := &lastState.Agents[i]
for _, agent := range lastState.agents {
disconnectedAgents[agent.Guid] = agent
}
for i := range state.Agents {
agent := &state.Agents[i]
if _, ok := findAgent(lastState, agent.Guid); !ok {
for _, agent := range state.agents {
if lastState.agents[agent.Guid] == nil {
cumulativeAgentCount.Inc()
}
delete(disconnectedAgents, agent.Guid)
@ -256,17 +255,15 @@ func updateMetricsImpl(state *models.State) {
removeAgentMetrics(agent)
}
clientCount.Set(float64(len(state.Clients)))
clientCount.Set(float64(len(state.clients)))
// with this app
disconnectedClients := make(map[string]*models.Client)
for i := range lastState.Clients {
client := &lastState.Clients[i]
for _, client := range lastState.clients {
disconnectedClients[client.Guid] = client
}
for i := range state.Clients {
client := &state.Clients[i]
if _, ok := findClient(lastState, client.Guid); !ok {
for _, client := range state.clients {
if lastState.clients[client.Guid] == nil {
cumulativeClientCount.Inc()
}
delete(disconnectedClients, client.Guid)