Skip to content

Instantly share code, notes, and snippets.

@instabledesign
Created June 13, 2019 14:36
Show Gist options
  • Save instabledesign/930e21119c341a994e6948e07e263ddb to your computer and use it in GitHub Desktop.
Save instabledesign/930e21119c341a994e6948e07e263ddb to your computer and use it in GitHub Desktop.
Golang simple signal dispatcher
package signal_dispatcher
import (
"os"
"os/signal"
)
type SignalSubscriber interface {
GetSubscribesSignals() *map[os.Signal]bool
Notify(os.Signal)
}
type SignalSubscriberCallback struct {
signals *map[os.Signal]bool
callback func(os.Signal)
}
func (s *SignalSubscriberCallback) GetSubscribesSignals() *map[os.Signal]bool {
return s.signals
}
func (s *SignalSubscriberCallback) Notify(signal os.Signal) {
s.callback(signal)
}
type SignalDispatcher struct {
signalChan chan os.Signal
stopChan chan bool
subscribers []SignalSubscriber
}
func (s *SignalDispatcher) Subscribe(callback func(os.Signal), sig ...os.Signal) *SignalDispatcher {
var signals *map[os.Signal]bool
if sig != nil {
signals := &map[os.Signal]bool{}
for _, s := range sig {
(*signals)[s] = true
}
}
s.subscribers = append(s.subscribers, &SignalSubscriberCallback{callback: callback, signals: signals})
return s
}
func (s *SignalDispatcher) Listen() *SignalDispatcher {
s.signalChan = make(chan os.Signal, 1)
s.stopChan = make(chan bool, 1)
signal.Notify(s.signalChan)
go func() {
for {
select {
case <-s.stopChan:
signal.Stop(s.signalChan)
close(s.stopChan)
close(s.signalChan)
return
case sig := <-s.signalChan:
for _, subscriber := range s.subscribers {
signals := subscriber.GetSubscribesSignals()
if signals != nil {
if _, ok := (*signals)[sig]; !ok {
continue
}
}
subscriber.Notify(sig)
}
}
}
}()
return s
}
func (s *SignalDispatcher) Stop() *SignalDispatcher {
s.stopChan <- true
return s
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment