github.com/verrazzano/verrazzano@v1.7.0/platform-operator/internal/monitor/monitor.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package monitor 5 6 import ( 7 ctrlerrors "github.com/verrazzano/verrazzano/pkg/controller/errors" 8 ) 9 10 // BackgroundProcessMonitor - Represents a monitor object used by the component to monitor a background goroutine used for running 11 // install, uninstall, etc. operations asynchronously. 12 type BackgroundProcessMonitor interface { 13 // CheckResult - Checks for a result from the goroutine; returns either the result of the operation, or an error indicating 14 // the operation is still in progress 15 CheckResult() (bool, error) 16 // Reset - Resets the monitor and closes any open channels 17 Reset() 18 // IsRunning - returns true of the monitor/goroutine are active 19 IsRunning() bool 20 // IsCompleted - returns true if the monitor has run and marked as completed 21 IsCompleted() bool 22 // SetCompleted - sets the monitor thread to true 23 SetCompleted() 24 // Run - Run the operation with the specified args in a background goroutine 25 Run(operation BackgroundFunc) 26 } 27 28 // BackgroundFunc - the operation to be called in the background goroutine 29 type BackgroundFunc func() error 30 31 // BackgroundProcessMonitorType - a monitor. &BackgroundProcessMonitorType acts as an implementation of BackgroundProcessMonitor 32 type BackgroundProcessMonitorType struct { 33 ComponentName string 34 running bool 35 completed bool 36 resultCh chan bool 37 } 38 39 // CheckResult - checks for a result from the goroutine 40 // - returns false and a retry error if it's still running, or the result from the channel and nil if an answer was received 41 func (m *BackgroundProcessMonitorType) CheckResult() (bool, error) { 42 select { 43 case result := <-m.resultCh: 44 return result, nil 45 default: 46 return false, ctrlerrors.RetryableError{Source: m.ComponentName} 47 } 48 } 49 50 // Reset - reset the monitor and close the channel 51 func (m *BackgroundProcessMonitorType) Reset() { 52 m.running = false 53 m.completed = false 54 close(m.resultCh) 55 } 56 57 // IsRunning - returns true if the monitor/goroutine are active 58 func (m *BackgroundProcessMonitorType) IsRunning() bool { 59 return m.running 60 } 61 62 // IsCompleted - returns true if the monitor/goroutine is completed 63 func (m *BackgroundProcessMonitorType) IsCompleted() bool { 64 return m.completed 65 } 66 67 // SetCompleted - sets the monitor thread as completed 68 func (m *BackgroundProcessMonitorType) SetCompleted() { 69 m.completed = true 70 m.running = false 71 } 72 73 // Run - calls the operation in a background goroutine 74 func (m *BackgroundProcessMonitorType) Run(operation BackgroundFunc) { 75 m.running = true 76 m.resultCh = make(chan bool, 2) 77 78 go func(outputChan chan bool) { 79 // The function will execute once, sending true on success, false on failure to the channel reader 80 err := operation() 81 if err != nil { 82 outputChan <- false 83 return 84 } 85 outputChan <- true 86 }(m.resultCh) 87 } 88 89 // Check that &BackgroundProcessMonitorType implements BackgroundProcessMonitor 90 var _ BackgroundProcessMonitor = &BackgroundProcessMonitorType{}