Created
April 17, 2020 00:06
-
-
Save clarkmcc/b2e6b548312a55091bca527a34cc5f3b to your computer and use it in GitHub Desktop.
StopInformerMap provides an easy interface for interacting with named stop informers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package concurrency | |
import ( | |
"sync" | |
) | |
// StopInformerMap provides an easy interface for interacting with named stop informers | |
type StopInformerMap interface { | |
// Starts a new named stop informer | |
Start(name string, informer StopInformer) | |
// Starts a new named stop informer and returns it for method chaining | |
StartAndReturn(name string, informer StopInformer) StopInformer | |
// Returns a stop informer | |
Get(name string) StopInformer | |
// Returns whether a stop informer exists | |
Exists(name string) bool | |
// Iterates over all stop informers and sends the stop notification to each; this method | |
// blocks until all informers acknowledge the stop command | |
StopAll() | |
// Iterates over all stop informers and sends the stop notification to each; this method | |
// returns a channel and sends a value when all informers acknowledge they're stopped | |
StopAllAndNotify(buffer int) SingleStructChan | |
} | |
type genericStopInformerMap struct { | |
informers map[string]StopInformer | |
m *sync.RWMutex | |
} | |
func NewGenericStopInformerMap() StopInformerMap { | |
return &genericStopInformerMap{ | |
informers: map[string]StopInformer{}, | |
m: &sync.RWMutex{}, | |
} | |
} | |
// Starts a new named stop informer | |
func (g *genericStopInformerMap) Start(name string, informer StopInformer) { | |
g.m.Lock() | |
defer g.m.Unlock() | |
g.informers[name] = informer | |
} | |
// Starts a new named stop informer and returns it for method chaining | |
func (g *genericStopInformerMap) StartAndReturn(name string, informer StopInformer) StopInformer { | |
g.m.Lock() | |
defer g.m.Unlock() | |
g.informers[name] = informer | |
return informer | |
} | |
// Returns a stop informer | |
func (g *genericStopInformerMap) Get(name string) StopInformer { | |
g.m.RLock() | |
defer g.m.RUnlock() | |
if i, ok := g.informers[name]; ok { | |
return i | |
} | |
return NewGenericStopInformer().ResolveImmediately() | |
} | |
// Returns whether a stop informer exists | |
func (g *genericStopInformerMap) Exists(name string) bool { | |
g.m.RLock() | |
defer g.m.RUnlock() | |
if _, ok := g.informers[name]; ok { | |
return true | |
} | |
return false | |
} | |
// Iterates over all stop informers and sends the stop notification to each; this method | |
// blocks until all informers acknowledge the stop command | |
func (g *genericStopInformerMap) StopAll() { | |
g.m.Lock() | |
defer g.m.Unlock() | |
for key, informer := range g.informers { | |
informer.Stop() | |
delete(g.informers, key) | |
} | |
} | |
// Iterates over all stop informers and sends the stop notification to each; this method | |
// returns a channel and sends a value when all informers acknowledge they're stopped | |
func (g *genericStopInformerMap) StopAllAndNotify(buffer int) SingleStructChan { | |
g.m.Lock() | |
defer g.m.Unlock() | |
notifyChan := make(SingleStructChan, buffer) | |
wg := &sync.WaitGroup{} | |
for _, informer := range g.informers { | |
wg.Add(1) | |
go func(informer StopInformer, wg *sync.WaitGroup) { | |
defer wg.Done() | |
<- informer.StopAndNotify(0) | |
}(informer, wg) | |
} | |
go func() { | |
wg.Done() | |
notifyChan <- struct{}{} | |
}() | |
return notifyChan | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment