func Start(dq mailbox.Dequeuer, conf jamon.Group) error { pause, err := strconv.Atoi(conf.Get("pause")) if err != nil { log.Fatal("agent/pause configuration is not numeric") } cron := cronJob{ dq: dq, config: conf, failed: make(chan report), done: make(chan report), retry: make(chan report), } for { time.Sleep(time.Duration(pause) * time.Second) jobs, err := cron.dq.Dequeue() if err != nil { log.Printf("error dequeuing: %s", err) continue } go func() { for { select { case r, more := <-cron.done: if !more { return } dq.Delivered(r.msgID, r.rcpt) case r := <-cron.retry: dq.Retry(r.msgID, r.rcpt, r.reason) case r := <-cron.failed: dq.Failed(r.msgID, r.rcpt, r.reason) } } }() var wg sync.WaitGroup wg.Add(len(jobs)) for host, pkg := range jobs { go func() { defer wg.Done() cron.deliverTo(host, pkg) }() } wg.Wait() close(cron.done) dq.Flush() } return nil }
// Start initiates a new SMTP server given an Enqueuer and a configuration. func Start(mq mailbox.Enqueuer, cfg jamon.Group) error { if !cfg.Has("listen") || !cfg.Has("host") { return ErrMinConfig } ln, err := net.Listen("tcp", cfg.Get("listen")) if err != nil { return err } srv := server{Enqueuer: mq, config: cfg} srv.spec = commandSpec{ "HELO": cmdHELO, "EHLO": cmdEHLO, "MAIL": cmdMAIL, "RCPT": cmdRCPT, "DATA": cmdDATA, "RSET": cmdRSET, "NOOP": cmdNOOP, "VRFY": cmdVRFY, "QUIT": cmdQUIT, } for { conn, err := ln.Accept() if err != nil { log.Printf("Error accepting an incoming connection: %s\r\n", err) continue } go srv.createTransaction(conn) } }