refactor emit() and emitwithcallback()
diff --git a/apid.go b/apid.go index fdf937c..4392b8f 100644 --- a/apid.go +++ b/apid.go
@@ -1,12 +1,15 @@ package apid import ( + "errors" "os" + "time" ) const ( SystemEventsSelector EventSelector = "system event" ShutdownEventSelector EventSelector = "shutdown event" + ShutdownTimeout int = 10 ) var ( @@ -15,8 +18,6 @@ pluginInitFuncs []PluginInitFunc services Services - - shutdownChan chan int ) type Services interface { @@ -49,8 +50,6 @@ ss.api = s.API() ss.data = s.Data() - shutdownChan = make(chan int) - ss.events.Emit(SystemEventsSelector, APIDInitializedEvent) } @@ -76,21 +75,22 @@ log.Debugf("done initializing plugins") } -func ShutdownPlugins() { - Events().EmitWithCallback(ShutdownEventSelector, ShutdownEvent{"apid is going to shutdown"}, shutdownHandler) -} - -func shutdownHandler(event Event) { - log := Log() - log.Debugf("shutdown apid") - shutdownChan <- 1 -} - -/* wait for the shutdown of registered graceful-shutdown plugins, blocking until the required plugins finish shutdown - * this is used to prevent the main from exiting - */ -func WaitPluginsShutdown() { - <-shutdownChan +// Shutdown all the plugins that have registered for ShutdownEventSelector. +// This call will block until either all required plugins shutdown, or a timeout occurred. +func ShutdownPluginsAndWait() error { + shutdownEvent := ShutdownEvent{"apid is going to shutdown"} + eventChan := Events().Emit(ShutdownEventSelector, shutdownEvent) + select { + case event := <-eventChan: + if e, ok := event.(ShutdownEvent); ok { + if e == shutdownEvent { + return nil + } + } + return errors.New("Emit() problem: wrong event delivered") + case <-time.After(time.Duration(ShutdownTimeout) * time.Second): + return errors.New("Shutdown timeout") + } } func AllServices() Services {
diff --git a/events_service.go b/events_service.go index 1106f2d..c11b358 100644 --- a/events_service.go +++ b/events_service.go
@@ -11,10 +11,9 @@ type EventHandlerFunc func(event Event) type EventsService interface { - /* publish an event to the selector. - It will send a copy of the delivered event to the returned channel, after all listeners have responded to the event. - Call "Emit()" for non-blocking, "<-Emit()" for blocking. - */ + // Publish an event to the selector. + // It will send a copy of the delivered event to the returned channel, after all listeners have responded to the event. + // Call "Emit()" for non-blocking, "<-Emit()" for blocking. Emit(selector EventSelector, event Event) chan Event // publish an event to the selector, call the passed handler when all listeners have responded to the event