Improve module failure status notify callback handling

This commit is contained in:
Daniel 2021-05-05 17:46:09 +02:00
parent 2157351757
commit 3f3786b854
3 changed files with 47 additions and 34 deletions

View file

@ -104,29 +104,34 @@ func (m *Module) Error(id, title, msg string) {
} }
func (m *Module) setFailure(status uint8, id, title, msg string) { func (m *Module) setFailure(status uint8, id, title, msg string) {
// Send an update before we override a previous failure. // Copy data for failure status update worker.
if failureUpdateNotifyFuncReady.IsSet() && m.failureID != "" { resolveFailureID := m.failureID
updateFailureID := m.failureID
m.StartWorker("failure status updater", func(context.Context) error {
// Only use data in worker that won't change anymore.
failureUpdateNotifyFunc(FailureNone, updateFailureID, "", "")
return nil
})
}
// Set new failure status.
m.failureStatus = status m.failureStatus = status
m.failureID = id m.failureID = id
m.failureTitle = title m.failureTitle = title
m.failureMsg = msg m.failureMsg = msg
if failureUpdateNotifyFuncReady.IsSet() { // Notify of module change.
m.StartWorker("failure status updater", func(context.Context) error {
// Only use data in worker that won't change anymore.
failureUpdateNotifyFunc(status, id, title, msg)
return nil
})
}
m.notifyOfChange() m.notifyOfChange()
// Propagate failure status.
if failureUpdateNotifyFuncReady.IsSet() {
m.newTask("failure status updater", func(context.Context, *Task) error {
// Only use data in worker that won't change anymore.
// Resolve previous failure state if available.
if resolveFailureID != "" {
failureUpdateNotifyFunc(FailureNone, resolveFailureID, "", "")
}
// Notify of new failure state.
failureUpdateNotifyFunc(status, id, title, msg)
return nil
}).QueuePrioritized()
}
} }
// Resolve removes the failure state from the module if the given failureID matches the current failure ID. If the given failureID is an empty string, Resolve removes any failure state. // Resolve removes the failure state from the module if the given failureID matches the current failure ID. If the given failureID is an empty string, Resolve removes any failure state.
@ -134,24 +139,32 @@ func (m *Module) Resolve(failureID string) {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if failureID == "" || failureID == m.failureID { // Check if resolving is necessary.
// Propagate resolving. if failureID != "" && failureID != m.failureID {
if failureUpdateNotifyFuncReady.IsSet() { // Return immediately if not resolving any (`""`) or if the failure ID
updateFailureID := m.failureID // does not match.
m.StartWorker("failure status updater", func(context.Context) error { return
// Only use data in worker that won't change anymore. }
failureUpdateNotifyFunc(FailureNone, updateFailureID, "", "")
return nil
})
}
// Set failure status on module. // Copy data for failure status update worker.
m.failureStatus = FailureNone resolveFailureID := m.failureID
m.failureID = ""
m.failureTitle = ""
m.failureMsg = ""
m.notifyOfChange() // Set failure status on module.
m.failureStatus = FailureNone
m.failureID = ""
m.failureTitle = ""
m.failureMsg = ""
// Notify of module change.
m.notifyOfChange()
// Propagate failure status.
if failureUpdateNotifyFuncReady.IsSet() {
m.newTask("failure status updater", func(context.Context, *Task) error {
// Only use data in worker that won't change anymore.
failureUpdateNotifyFunc(FailureNone, resolveFailureID, "", "")
return nil
}).QueuePrioritized()
} }
} }

View file

@ -9,7 +9,7 @@ import (
// notification will be reflected on the module failure status. // notification will be reflected on the module failure status.
func (n *Notification) AttachToModule(m *modules.Module) { func (n *Notification) AttachToModule(m *modules.Module) {
if m == nil { if m == nil {
log.Warningf("notifications: cannot remove attached module from notification %s", n.EventID) log.Warningf("notifications: invalid usage: cannot attach %s to nil module", n.EventID)
return return
} }

View file

@ -112,7 +112,7 @@ type Action struct {
// ID specifies a unique ID for the action. If an action is selected, the ID // ID specifies a unique ID for the action. If an action is selected, the ID
// is written to SelectedActionID and the notification is saved. // is written to SelectedActionID and the notification is saved.
// If the action type is not ActionTypeNone, the ID may be empty, signifying // If the action type is not ActionTypeNone, the ID may be empty, signifying
// that this action is merely additional and selecting it does dismiss the // that this action is merely additional and selecting it does not dismiss the
// notification. // notification.
ID string ID string
// Text on the button. // Text on the button.