diff --git a/internal/entityfiles/entityfiles.go b/internal/entityfiles/entityfiles.go index a9e18e8..fce9901 100644 --- a/internal/entityfiles/entityfiles.go +++ b/internal/entityfiles/entityfiles.go @@ -89,7 +89,7 @@ func loadEntityFileJson(filename string, entityname string) { data = append(data, d) } - updateEvmFromFile(entityname, data) + updateSvFromFile(entityname, data) } func loadEntityFileYaml(filename string, entityname string) { @@ -113,10 +113,12 @@ func loadEntityFileYaml(filename string, entityname string) { log.Errorf("Unmarshal: %v", err) } - updateEvmFromFile(entityname, data) + updateSvFromFile(entityname, data) } -func updateEvmFromFile(entityname string, data []map[string]string) { +func updateSvFromFile(entityname string, data []map[string]string) { + log.Debugf("updateSvFromFile: %+v", data) + count := len(data) sv.RemoveKeysThatStartWith("entities." + entityname) diff --git a/internal/filehelper/file_change_notify.go b/internal/filehelper/file_change_notify.go index 89f3c22..ed000f7 100644 --- a/internal/filehelper/file_change_notify.go +++ b/internal/filehelper/file_change_notify.go @@ -5,18 +5,27 @@ import ( log "github.com/sirupsen/logrus" "path/filepath" "time" + + "sync" ) var ( - debounceWriteLog map[string]time.Time + debounceWriteLog map[string]*FsNotifyLogEntry + + debounceWriteLogMutex = sync.Mutex{} ) func init() { - debounceWriteLog = make(map[string]time.Time) + debounceWriteLog = make(map[string]*FsNotifyLogEntry) +} + +type FsNotifyLogEntry struct { + callbackWrapper *time.Timer + callbackComplete bool } const ( - debounceDelay = 300 + debounceDelay = 300 * time.Millisecond ) type watchContext struct { @@ -117,22 +126,44 @@ func consumeEvent(ok bool, ctx *watchContext) bool { func consumeRelevantEvents(ctx *watchContext) { if ctx.event.Has(ctx.interestedEvent) { - log.Debugf("fsnotify write event: %v", ctx.event) + log.Debugf("fsnotify event relevant: %v", ctx.event) processDebounce(ctx) } else { - log.Debugf("fsnotify irrelevant event on file %v", ctx.event) + log.Debugf("fsnotify event irrelevant: %v", ctx.event) } } func processDebounce(ctx *watchContext) { - entry, found := debounceWriteLog[ctx.filename] + debounceWriteLogMutex.Lock() - if !found || time.Since(entry) < debounceDelay { - debounceWriteLog[ctx.filename] = time.Now() + logEntry, found := debounceWriteLog[ctx.filename] - ctx.callback(ctx.event.Name) - } else { - log.Debugf("Supressing write event because it's within the debounce delay: %v", ctx.filename) + if !found { + logEntry = &FsNotifyLogEntry{ + callbackComplete: false, + callbackWrapper: nil, + } + + debounceWriteLog[ctx.filename] = logEntry } + + log.Infof("fsnotify event %+v", logEntry) + + if logEntry.callbackComplete || logEntry.callbackWrapper == nil { + log.Debugf("fsnotify event callback queued within debounce delay: %v", ctx.filename) + + logEntry.callbackComplete = false + logEntry.callbackWrapper = time.AfterFunc(debounceDelay, func() { + log.Debugf("fsnotify event callback being fired: %v", ctx.filename) + + ctx.callback(ctx.event.Name) + + logEntry.callbackComplete = true + }) + } else { + log.Debugf("fsnotify event suppressed because it's within the debounce delay: %v", ctx.filename) + } + + debounceWriteLogMutex.Unlock() } diff --git a/webui.dev/js/marshaller.js b/webui.dev/js/marshaller.js index f1e27fb..440e041 100644 --- a/webui.dev/js/marshaller.js +++ b/webui.dev/js/marshaller.js @@ -173,7 +173,7 @@ function marshalDashboardStructureToHtml (json) { const nav = document.getElementById('navigation-links') for (const dashboard of json.dashboards) { - const oldsection = document.querySelector('section[title="' + dashboard.title + '"]') + const oldsection = document.querySelector('section[title="' + dashboard.title.replace(' ', '') + '"]') if (oldsection != null) { oldsection.remove() diff --git a/webui.dev/main.js b/webui.dev/main.js index d4e2e3a..5aa1e36 100644 --- a/webui.dev/main.js +++ b/webui.dev/main.js @@ -134,7 +134,8 @@ function main () { initMarshaller() setupLogSearchBox() - window.addEventListener('EventConfigChanged', fetchGetDashboardComponents) // For websocket + window.addEventListener('EventConfigChanged', fetchGetDashboardComponents) + window.addEventListener('EventEntityChanged', fetchGetDashboardComponents) window.fetch('webUiSettings.json').then(res => { return res.json()