feat(node): add GetNodeCount to get node count and remove no need node update log, only log when node count changed
This commit is contained in:
+5
-5
@@ -46,7 +46,7 @@ var startupOnlySettings = []string{
|
||||
"dbPath",
|
||||
}
|
||||
|
||||
// RestartRequiredKeys lists the settings in patch that only take effect at
|
||||
// IsRestartRequiredKeys lists the settings in patch that only take effect at
|
||||
// startup, as dot-separated paths, in the order startupOnlySettings declares
|
||||
// them. Only config.json carries such settings; an update to one of the other
|
||||
// files always reports nothing.
|
||||
@@ -54,7 +54,7 @@ var startupOnlySettings = []string{
|
||||
// The write itself succeeds either way — this is advice for the user, not a
|
||||
// rejection. The result is never nil, so a caller can put it straight into a
|
||||
// JSON response and get [] rather than null.
|
||||
func RestartRequiredKeys(settingsType string, patch map[string]interface{}) []string {
|
||||
func IsRestartRequiredKeys(settingsType string, patch map[string]interface{}) []string {
|
||||
keys := []string{}
|
||||
if settingsType != SettingGlobal {
|
||||
return keys
|
||||
@@ -63,7 +63,7 @@ func RestartRequiredKeys(settingsType string, patch map[string]interface{}) []st
|
||||
patched := patchPaths(patch)
|
||||
for _, watched := range startupOnlySettings {
|
||||
for _, path := range patched {
|
||||
if pathsOverlap(path, watched) {
|
||||
if isPathsOverlap(path, watched) {
|
||||
keys = append(keys, watched)
|
||||
break
|
||||
}
|
||||
@@ -96,12 +96,12 @@ func patchPaths(patch map[string]interface{}) []string {
|
||||
return paths
|
||||
}
|
||||
|
||||
// pathsOverlap reports whether a patched path and a watched setting can affect
|
||||
// isPathsOverlap reports whether a patched path and a watched setting can affect
|
||||
// each other: they are the same key, the patch names something inside the
|
||||
// watched setting, or the patch names a section the watched setting lives in.
|
||||
// The last case matters because a patch may replace a whole section, which
|
||||
// changes every key under it.
|
||||
func pathsOverlap(patched, watched string) bool {
|
||||
func isPathsOverlap(patched, watched string) bool {
|
||||
return patched == watched ||
|
||||
strings.HasPrefix(patched, watched+".") ||
|
||||
strings.HasPrefix(watched, patched+".")
|
||||
|
||||
@@ -271,7 +271,7 @@ func TestRestartRequiredKeys(t *testing.T) {
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := RestartRequiredKeys(tc.settingsType, tc.patch)
|
||||
got := IsRestartRequiredKeys(tc.settingsType, tc.patch)
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("RestartRequiredKeys() = %v, want %v", got, tc.want)
|
||||
}
|
||||
@@ -287,7 +287,7 @@ func TestRestartRequiredKeys(t *testing.T) {
|
||||
func TestRestartRequiredKeysIsAdvisory(t *testing.T) {
|
||||
writeTempConfig(t, &global.ConfigPath.Global, `{"system":{"listenPort":"8080"}}`)
|
||||
|
||||
keys := RestartRequiredKeys(SettingGlobal, map[string]interface{}{
|
||||
keys := IsRestartRequiredKeys(SettingGlobal, map[string]interface{}{
|
||||
"system": map[string]interface{}{"listenPort": "9090"},
|
||||
})
|
||||
if len(keys) != 1 {
|
||||
|
||||
+1
-1
@@ -88,6 +88,6 @@ func SettingsSetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// it changed will not be live until the program is restarted.
|
||||
utils.SendSuccessResponse(w, "settings updated successfully", map[string]interface{}{
|
||||
"type": settingsType,
|
||||
"restartRequired": config.RestartRequiredKeys(settingsType, patch),
|
||||
"restartRequired": config.IsRestartRequiredKeys(settingsType, patch),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ func (c *Client) FetchNodes() ([]NodeInfo, error) {
|
||||
postLog.Warning("Failed to save bot node config: " + err.Error())
|
||||
}
|
||||
|
||||
postLog.Info(fmt.Sprintf("Fetched %d nodes from Komari", len(nodes)))
|
||||
// postLog.Debug(fmt.Sprintf("Fetched %d nodes from Komari", len(nodes)))
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ type StatusChangeCallback func(change StatusChange)
|
||||
// All methods are thread-safe.
|
||||
type Tracker struct {
|
||||
mu sync.RWMutex
|
||||
count int
|
||||
nodes map[string]*Node // uuid → Node
|
||||
uuidToName map[string]string // uuid → name (from node list)
|
||||
onlineSet map[string]bool // which uuids are currently online
|
||||
@@ -161,6 +162,13 @@ func (t *Tracker) fireCallbacks(change StatusChange) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetNodeCount returns the total number of nodes in the tracker.
|
||||
func (t *Tracker) GetNodeCount() int {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
return t.count
|
||||
}
|
||||
|
||||
// UpdateNodeList replaces the full node list and updates each node's name and
|
||||
// static Info metadata. entries maps UUID → node metadata from the Komari node
|
||||
// list.
|
||||
@@ -175,6 +183,8 @@ func (t *Tracker) UpdateNodeList(entries map[string]NodeListEntry) {
|
||||
t.knownUUIDs[uuid] = true
|
||||
}
|
||||
|
||||
t.count = len(entries)
|
||||
|
||||
t.uuidToName = make(map[string]string, len(entries))
|
||||
for uuid, entry := range entries {
|
||||
t.uuidToName[uuid] = entry.Name
|
||||
|
||||
@@ -260,11 +260,15 @@ func startBackgroundTasks(_ *config.Config) {
|
||||
if client == nil {
|
||||
continue
|
||||
}
|
||||
orgNodeCount := node.GetTracker().GetNodeCount()
|
||||
nodes, err := client.FetchNodes()
|
||||
if err != nil {
|
||||
postLog.Warning("Failed to refresh node list: " + err.Error())
|
||||
continue
|
||||
}
|
||||
if node.GetTracker().GetNodeCount() != orgNodeCount {
|
||||
postLog.Info(fmt.Sprintf("Refreshed node list: %d nodes", len(nodes)))
|
||||
}
|
||||
tracker := node.GetTracker()
|
||||
if tracker != nil {
|
||||
tracker.UpdateNodeList(komari.BuildNodeListData(nodes))
|
||||
|
||||
Reference in New Issue
Block a user