// Start will begin the worker cycle of claiming and executing tasks. The worker // will also being to respond to host level events such as shutdown notifications and // resource depletion events. func (w *Worker) Start() { w.log.Info("worker starting up") // Ensure that server is stopping gracefully serverStopped := atomics.NewBool(false) go func() { err := w.server.ListenAndServe() if !serverStopped.Get() { w.log.Errorf("ListenAndServe failed for webhookserver, error: %s", err) } }() go w.tm.Start() select { case <-w.sm.WaitForShutdown(): case <-w.done: } w.tm.Stop() // Allow server to stop serverStopped.Set(true) w.server.Stop() return }
func (m *taskPluginManager) Stopped(r engines.ResultSet) (bool, error) { // Sanity check that no two methods on plugin is running in parallel, this way // plugins don't have to be thread-safe, and we ensure nothing is called after // Dispose() has been called. if m.working.Swap(true) { panic("Another plugin method is currently running, or Dispose() has been called!") } defer m.working.Set(false) // Use atomic bool to return true, if no plugin returns false result := atomics.NewBool(true) // Run method on plugins in parallel errors := make(chan error) for _, p := range m.taskPlugins { go func(p TaskPlugin) { success, err := p.Stopped(r) if !success { result.Set(false) } errors <- err }(p) } return result.Get(), waitForErrors(errors, len(m.taskPlugins)) }