One way could to be to utilize channels.
Your central code which manages/changes the property or variable that needs to be listened may provide a GetChan()
function which returns a channel on which modifications (e.g. new values) will be broadcasted:
// The variable or property that is listened:
var i int
// Slice of all listeners
var listeners []chan int
func GetChan() chan int {
listener := make(chan int, 5)
listeners = append(listeners, listener)
return listener
}
Whenever you change the variable/property, you need to broadcast the change:
func Set(newi int) {
i = newi
for _, ch := range listeners {
ch <- i
}
}
And listeners need to "listen" for change events, which can be done by a for range
loop on the channel returned by GetChan()
:
func Background(name string, ch chan int, done chan int) {
for v := range ch {
fmt.Printf("[%s] value changed: %d\n", name, v)
}
done <- 0
}
Here is the main program:
func main() {
l1 := GetChan()
l2 := GetChan()
done := make(chan int)
go Background("B1", l1, done)
go Background("B2", l2, done)
Set(3)
time.Sleep(time.Second) // Wait a little
Set(5)
// Close all listeners:
for _, listener := range listeners {
close(listener)
}
// Wait 2 background threads to finish:
<-done
<-done
}
And its output:
[B1] value changed: 3
[B2] value changed: 3
[B1] value changed: 5
[B2] value changed: 5
You can try the complete program on the Go Playground.
You may also implement a "broker" which realizes a subscriber model and allows broadcasting messages. See How to broadcast message using channel.