func handleClient(conn net.Conn, c chan *email.SMTPEmail) { client := client.MakeClient(conn) defer client.Close() // close on shutdown using strategy from http://stackoverflow.com/a/13419724 quit := false id, shutdownRequested := shutdown.AddShutdownListener("Client processor") defer shutdown.RoutineDone(id) go func() { <-shutdownRequested quit = true client.Close() }() err := client.BeginReceive(c) if err != nil { if quit { log.Info("Shutting down client") return } log.WithFields(log.Fields{ "error": err.Error(), }).Info("error encountered, closing client connection") } }
// Listens for connections on the given listener and puts them in the channel. // Blocks while still receiving connections. // Returns an error on network problem, or nil if shutdown requested func listenForConnections(l net.Listener, c chan net.Conn) error { id, shutdownRequested := shutdown.AddShutdownListener("Connection listener") defer shutdown.RoutineDone(id) log.WithFields(log.Fields{ "listening_on": fmt.Sprintf("%v", l.Addr()), "fqdn": config.GetFQDN(), }).Info("Starting connection listener") // shutdown using the strategy found here http://stackoverflow.com/a/13419724 quit := false go func() { <-shutdownRequested quit = true l.Close() }() for { conn, err := l.Accept() if err != nil { if quit { log.Info("Shutting down connection listener") return nil } l.Close() return err } c <- conn } }
func handleClients(cxnChan chan net.Conn, emChan chan *email.SMTPEmail) { id, shutdownRequested := shutdown.AddShutdownListener("Client handler") defer shutdown.RoutineDone(id) for { select { case cxn := <-cxnChan: go handleClient(cxn, emChan) case <-shutdownRequested: log.Info("Shutting down client handler") return } } }
func (b *MemoryBackend) continuousCleanup() { id, shutdownRequested := shutdown.AddShutdownListener("MemoryBackend cleanup") defer shutdown.RoutineDone(id) for { select { case <-time.After(config.GetEmailTTL() / 4): b.doCleanup() case <-shutdownRequested: log.Info("Shutting down memory cleanup with system") return case <-b.quit: log.Info("Quitting memory cleanup") return } } }