github.com/m3db/m3@v1.5.0/src/query/storage/m3/cluster_namespaces_watcher.go (about) 1 // Copyright (c) 2020 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package m3 22 23 import ( 24 xresource "github.com/m3db/m3/src/x/resource" 25 xwatch "github.com/m3db/m3/src/x/watch" 26 ) 27 28 type clusterNamespacesWatcher struct { 29 watchable xwatch.Watchable 30 } 31 32 // NewClusterNamespacesWatcher creates a new ClusterNamespacesWatcher. 33 func NewClusterNamespacesWatcher() ClusterNamespacesWatcher { 34 watchable := xwatch.NewWatchable() 35 return &clusterNamespacesWatcher{watchable: watchable} 36 } 37 38 func (n *clusterNamespacesWatcher) Update(namespaces ClusterNamespaces) error { 39 return n.watchable.Update(namespaces) 40 } 41 42 func (n *clusterNamespacesWatcher) Get() ClusterNamespaces { 43 value := n.watchable.Get() 44 if value == nil { 45 return nil 46 } 47 48 return value.(ClusterNamespaces) 49 } 50 51 // RegisterListener registers the provided listener and returns a closer to clean up the watch. 52 // If the watcher is already closed, nothing is registered. 53 func (n *clusterNamespacesWatcher) RegisterListener( 54 listener ClusterNamespacesListener, 55 ) xresource.SimpleCloser { 56 if n.watchable.IsClosed() { 57 return xresource.SimpleCloserFn(func() {}) 58 } 59 _, watch, _ := n.watchable.Watch() 60 61 namespaces := watch.Get() 62 63 // Deliver the current cluster namespaces, synchronously, if already set. 64 if namespaces != nil { 65 <-watch.C() // Consume initial notification 66 listener.OnUpdate(namespaces.(ClusterNamespaces)) 67 } 68 69 // Spawn a new goroutine to listen for updates. 70 go func() { 71 for range watch.C() { 72 listener.OnUpdate(watch.Get().(ClusterNamespaces)) 73 } 74 }() 75 76 return watch 77 } 78 79 func (n *clusterNamespacesWatcher) Close() { 80 n.watchable.Close() 81 }