refactor: create heartbeats func in HubStore

This commit is contained in:
2026-05-09 22:31:42 +03:00
parent f2d0924bca
commit 6277523b23
9 changed files with 158 additions and 11 deletions
+12 -2
View File
@@ -1,5 +1,7 @@
package domain package domain
import "time"
type AgentRequest struct { type AgentRequest struct {
RequestID string RequestID string
Name string Name string
@@ -28,7 +30,15 @@ type SystemMetrics struct {
DiskUsage float64 DiskUsage float64
} }
type Heartbeat struct { type HeartbeatModel struct {
Timestamp string ID int
AgentID string
Timestamp time.Time
Metrics SystemMetrics
}
type CreateHeartbeatModel struct {
AgentID string
Timestamp time.Time
Metrics SystemMetrics Metrics SystemMetrics
} }
@@ -1,10 +1,10 @@
CREATE TABLE heartbeats ( CREATE TABLE heartbeats (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id VARCHAR(32) UNIQUE NOT NULL, agent_id VARCHAR(32) UNIQUE NOT NULL,
cpu_usage FLOAT, cpu_usage FLOAT NOT NULL ,
memory_usage FLOAT, memory_usage FLOAT NOT NULL ,
disk_usage FLOAT, disk_usage FLOAT NOT NULL ,
heartbeat_timestamp TIMESTAMP heartbeat_timestamp TIMESTAMP NOT NULL,
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
); );
+24
View File
@@ -76,3 +76,27 @@ func toDomainCapabilities(caps []byte) []domain.Capability {
} }
return capabilities return capabilities
} }
func toDBHeartbeat(heartbeat domainHub.CreateHeartbeatModel) gen2.InsertHeartbeatParams {
return gen2.InsertHeartbeatParams{
AgentID: heartbeat.AgentID,
HeartbeatTimestamp: heartbeat.Timestamp,
CpuUsage: heartbeat.Metrics.CpuUsage,
DiskUsage: heartbeat.Metrics.DiskUsage,
MemoryUsage: heartbeat.Metrics.MemoryUsage,
}
}
func toHeartBeatModel(heartbeat gen2.Heartbeat) domainHub.HeartbeatModel {
return domainHub.HeartbeatModel{
Timestamp: heartbeat.HeartbeatTimestamp,
AgentID: heartbeat.AgentID,
ID: int(heartbeat.ID),
Metrics: domainHub.SystemMetrics{
CpuUsage: heartbeat.CpuUsage,
DiskUsage: heartbeat.DiskUsage,
MemoryUsage: heartbeat.MemoryUsage,
},
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.30.0 // sqlc v1.31.1
// source: agent.sql // source: agent.sql
package gen package gen
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.30.0 // sqlc v1.31.1
package gen package gen
@@ -0,0 +1,75 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: heartbeat.sql
package gen
import (
"context"
"time"
)
const insertHeartbeat = `-- name: InsertHeartbeat :exec
INSERT INTO heartbeats (agent_id, cpu_usage, memory_usage, disk_usage, heartbeat_timestamp)
VALUES (?1, ?2, ?3, ?4, ?5)
`
type InsertHeartbeatParams struct {
AgentID string
CpuUsage float64
MemoryUsage float64
DiskUsage float64
HeartbeatTimestamp time.Time
}
func (q *Queries) InsertHeartbeat(ctx context.Context, arg InsertHeartbeatParams) error {
_, err := q.db.ExecContext(ctx, insertHeartbeat,
arg.AgentID,
arg.CpuUsage,
arg.MemoryUsage,
arg.DiskUsage,
arg.HeartbeatTimestamp,
)
return err
}
const selectHeartbeatsAfter = `-- name: SelectHeartbeatsAfter :many
SELECT id, agent_id, cpu_usage, memory_usage, disk_usage, heartbeat_timestamp FROM heartbeats
WHERE agent_id = ?1 AND heartbeat_timestamp > ?2
`
type SelectHeartbeatsAfterParams struct {
AgentID string
Timestamp time.Time
}
func (q *Queries) SelectHeartbeatsAfter(ctx context.Context, arg SelectHeartbeatsAfterParams) ([]Heartbeat, error) {
rows, err := q.db.QueryContext(ctx, selectHeartbeatsAfter, arg.AgentID, arg.Timestamp)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Heartbeat
for rows.Next() {
var i Heartbeat
if err := rows.Scan(
&i.ID,
&i.AgentID,
&i.CpuUsage,
&i.MemoryUsage,
&i.DiskUsage,
&i.HeartbeatTimestamp,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
+10 -1
View File
@@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.30.0 // sqlc v1.31.1
package gen package gen
@@ -19,3 +19,12 @@ type Agent struct {
Capabilities *string Capabilities *string
RegisteredAt time.Time RegisteredAt time.Time
} }
type Heartbeat struct {
ID int64
AgentID string
CpuUsage float64
MemoryUsage float64
DiskUsage float64
HeartbeatTimestamp time.Time
}
@@ -0,0 +1,7 @@
-- name: InsertHeartbeat :exec
INSERT INTO heartbeats (agent_id, cpu_usage, memory_usage, disk_usage, heartbeat_timestamp)
VALUES (:agent_id, :cpu_usage, :memory_usage, :disk_usage, :heartbeat_timestamp);
-- name: SelectHeartbeatsAfter :many
SELECT * FROM heartbeats
WHERE agent_id = :agent_id AND heartbeat_timestamp > :timestamp;
+24 -2
View File
@@ -3,6 +3,7 @@ package store
import ( import (
"context" "context"
"database/sql" "database/sql"
"time"
domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain" domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain"
"github.com/lorsanstand/HomeOps-Hub/hub/internal/store/sqlc/gen" "github.com/lorsanstand/HomeOps-Hub/hub/internal/store/sqlc/gen"
@@ -21,8 +22,8 @@ func (h *HubStore) NewAgent(ctx context.Context, agent domainHub.CreateAgentMode
return h.queries.CreateAgent(ctx, toDBAgent(agent)) return h.queries.CreateAgent(ctx, toDBAgent(agent))
} }
func (h *HubStore) GetAgentByAgentID(ctx context.Context, AgentID string) (domainHub.AgentModel, error) { func (h *HubStore) GetAgentByAgentID(ctx context.Context, agentID string) (domainHub.AgentModel, error) {
data, err := h.queries.GetAgentByAgentID(ctx, AgentID) data, err := h.queries.GetAgentByAgentID(ctx, agentID)
if err != nil { if err != nil {
return domainHub.AgentModel{}, err return domainHub.AgentModel{}, err
} }
@@ -34,3 +35,24 @@ func (h *HubStore) UpdateAgentByID(ctx context.Context, ID int, updateAgent doma
data.ID = int64(ID) data.ID = int64(ID)
return h.queries.UpdateAgentByID(ctx, data) return h.queries.UpdateAgentByID(ctx, data)
} }
func (h *HubStore) CreateHeartbeat(ctx context.Context, heartbeat domainHub.CreateHeartbeatModel) error {
data := toDBHeartbeat(heartbeat)
return h.queries.InsertHeartbeat(ctx, data)
}
func (h *HubStore) GetHeartbeatsByIDAfter(ctx context.Context, agentID string, timestamp time.Time) ([]domainHub.HeartbeatModel, error) {
data := gen.SelectHeartbeatsAfterParams{AgentID: agentID, Timestamp: timestamp}
heartbeats, err := h.queries.SelectHeartbeatsAfter(ctx, data)
if err != nil {
return []domainHub.HeartbeatModel{}, err
}
heartbeatsModel := make([]domainHub.HeartbeatModel, len(heartbeats))
for i, heartbeat := range heartbeats {
heartbeatsModel[i] = toHeartBeatModel(heartbeat)
}
return heartbeatsModel, nil
}