mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-22 05:36:15 +01:00
change to atomic.bool for fetching details / smart
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
@@ -29,20 +29,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
Id string `db:"id"`
|
Id string `db:"id"`
|
||||||
Host string `db:"host"`
|
Host string `db:"host"`
|
||||||
Port string `db:"port"`
|
Port string `db:"port"`
|
||||||
Status string `db:"status"`
|
Status string `db:"status"`
|
||||||
manager *SystemManager // Manager that this system belongs to
|
manager *SystemManager // Manager that this system belongs to
|
||||||
client *ssh.Client // SSH client for fetching data
|
client *ssh.Client // SSH client for fetching data
|
||||||
data *system.CombinedData // system data from agent
|
data *system.CombinedData // system data from agent
|
||||||
ctx context.Context // Context for stopping the updater
|
ctx context.Context // Context for stopping the updater
|
||||||
cancel context.CancelFunc // Stops and removes system from updater
|
cancel context.CancelFunc // Stops and removes system from updater
|
||||||
WsConn *ws.WsConn // Handler for agent WebSocket connection
|
WsConn *ws.WsConn // Handler for agent WebSocket connection
|
||||||
agentVersion semver.Version // Agent version
|
agentVersion semver.Version // Agent version
|
||||||
updateTicker *time.Ticker // Ticker for updating the system
|
updateTicker *time.Ticker // Ticker for updating the system
|
||||||
smartOnce sync.Once // Once for fetching and saving smart devices
|
detailsFetched atomic.Bool // True if static system details have been fetched and saved
|
||||||
detailsOnce sync.Once // Once for fetching and saving static system details
|
smartFetched atomic.Bool // True if SMART devices have been fetched and saved
|
||||||
|
smartFetching atomic.Bool // True if SMART devices are currently being fetched
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SystemManager) NewSystem(systemId string) *System {
|
func (sm *SystemManager) NewSystem(systemId string) *System {
|
||||||
@@ -118,10 +119,10 @@ func (sys *System) update() error {
|
|||||||
options := common.DataRequestOptions{
|
options := common.DataRequestOptions{
|
||||||
CacheTimeMs: uint16(interval),
|
CacheTimeMs: uint16(interval),
|
||||||
}
|
}
|
||||||
// fetch system details only on the first update
|
// fetch system details if not already fetched
|
||||||
sys.detailsOnce.Do(func() {
|
if !sys.detailsFetched.Load() {
|
||||||
options.IncludeDetails = true
|
options.IncludeDetails = true
|
||||||
})
|
}
|
||||||
data, err := sys.fetchDataFromAgent(options)
|
data, err := sys.fetchDataFromAgent(options)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = sys.createRecords(data)
|
_, err = sys.createRecords(data)
|
||||||
@@ -150,17 +151,11 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
}
|
}
|
||||||
hub := sys.manager.hub
|
hub := sys.manager.hub
|
||||||
err = hub.RunInTransaction(func(txApp core.App) error {
|
err = hub.RunInTransaction(func(txApp core.App) error {
|
||||||
if data.Details != nil {
|
// add system_stats record
|
||||||
if err := createSystemDetailsRecord(txApp, data.Details, sys.Id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add system_stats and container_stats records
|
|
||||||
systemStatsCollection, err := txApp.FindCachedCollectionByNameOrId("system_stats")
|
systemStatsCollection, err := txApp.FindCachedCollectionByNameOrId("system_stats")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
systemStatsRecord := core.NewRecord(systemStatsCollection)
|
systemStatsRecord := core.NewRecord(systemStatsCollection)
|
||||||
systemStatsRecord.Set("system", systemRecord.Id)
|
systemStatsRecord.Set("system", systemRecord.Id)
|
||||||
systemStatsRecord.Set("stats", data.Stats)
|
systemStatsRecord.Set("stats", data.Stats)
|
||||||
@@ -168,14 +163,14 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
if err := txApp.SaveNoValidate(systemStatsRecord); err != nil {
|
if err := txApp.SaveNoValidate(systemStatsRecord); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add containers and container_stats records
|
||||||
if len(data.Containers) > 0 {
|
if len(data.Containers) > 0 {
|
||||||
// add / update containers records
|
|
||||||
if data.Containers[0].Id != "" {
|
if data.Containers[0].Id != "" {
|
||||||
if err := createContainerRecords(txApp, data.Containers, sys.Id); err != nil {
|
if err := createContainerRecords(txApp, data.Containers, sys.Id); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add new container_stats record
|
|
||||||
containerStatsCollection, err := txApp.FindCachedCollectionByNameOrId("container_stats")
|
containerStatsCollection, err := txApp.FindCachedCollectionByNameOrId("container_stats")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -196,9 +191,16 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add system details record
|
||||||
|
if data.Details != nil {
|
||||||
|
if err := createSystemDetailsRecord(txApp, data.Details, sys.Id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sys.detailsFetched.Store(true)
|
||||||
|
}
|
||||||
|
|
||||||
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
|
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
|
||||||
systemRecord.Set("status", up)
|
systemRecord.Set("status", up)
|
||||||
|
|
||||||
systemRecord.Set("info", data.Info)
|
systemRecord.Set("info", data.Info)
|
||||||
if err := txApp.SaveNoValidate(systemRecord); err != nil {
|
if err := txApp.SaveNoValidate(systemRecord); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -208,15 +210,21 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
|
|
||||||
// Fetch and save SMART devices when system first comes online
|
// Fetch and save SMART devices when system first comes online
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sys.smartOnce.Do(func() {
|
if !sys.smartFetched.Load() && sys.smartFetching.CompareAndSwap(false, true) {
|
||||||
go sys.FetchAndSaveSmartDevices()
|
go func() {
|
||||||
})
|
defer sys.smartFetching.Store(false)
|
||||||
|
if err := sys.FetchAndSaveSmartDevices(); err == nil {
|
||||||
|
sys.smartFetched.Store(true)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return systemRecord, err
|
return systemRecord, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSystemDetailsRecord(app core.App, data *system.Details, systemId string) error {
|
func createSystemDetailsRecord(app core.App, data *system.Details, systemId string) error {
|
||||||
|
collectionName := "system_details"
|
||||||
params := dbx.Params{
|
params := dbx.Params{
|
||||||
"id": systemId,
|
"id": systemId,
|
||||||
"system": systemId,
|
"system": systemId,
|
||||||
@@ -232,12 +240,11 @@ func createSystemDetailsRecord(app core.App, data *system.Details, systemId stri
|
|||||||
"podman": data.Podman,
|
"podman": data.Podman,
|
||||||
"updated": time.Now().UTC(),
|
"updated": time.Now().UTC(),
|
||||||
}
|
}
|
||||||
queryString := `INSERT INTO system_details (id, system, hostname, kernel, cores, threads, cpu, os, os_name, arch, memory, podman, updated)
|
result, err := app.DB().Update(collectionName, params, dbx.HashExp{"id": systemId}).Execute()
|
||||||
VALUES ({:id}, {:system}, {:hostname}, {:kernel}, {:cores}, {:threads}, {:cpu}, {:os}, {:os_name}, {:arch}, {:memory}, {:podman}, {:updated})
|
rowsAffected, _ := result.RowsAffected()
|
||||||
ON CONFLICT(id) DO UPDATE SET system = excluded.system, hostname = excluded.hostname, kernel = excluded.kernel, cores = excluded.cores,
|
if err != nil || rowsAffected == 0 {
|
||||||
threads = excluded.threads, cpu = excluded.cpu, os = excluded.os, os_name = excluded.os_name, arch = excluded.arch,
|
_, err = app.DB().Insert(collectionName, params).Execute()
|
||||||
memory = excluded.memory, podman = excluded.podman, updated = excluded.updated`
|
}
|
||||||
_, err := app.DB().NewQuery(queryString).Bind(params).Execute()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user