示例#1
0
文件: server.go 项目: gbbr/gomez
// 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)
	}
}
示例#2
0
文件: agent.go 项目: gbbr/gomez
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
}