1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00

Add a skeleton queue

This patch introduces a basic, in-memory queue that only holds emails for now.

This slows down the benchmarks because we don't yet have a way to wait for
delivery (even if fake), that will come in later patches.
This commit is contained in:
Alberto Bertogli
2015-10-31 16:48:01 +00:00
parent 701f359634
commit 58de5a6200
4 changed files with 273 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ import (
"time"
"blitiri.com.ar/go/chasquid/internal/config"
"blitiri.com.ar/go/chasquid/internal/queue"
"blitiri.com.ar/go/chasquid/internal/systemd"
_ "net/http/pprof"
@@ -119,12 +120,16 @@ type Server struct {
// Time we wait for command round-trips (excluding DATA).
commandTimeout time.Duration
// Queue where we put incoming mail.
queue *queue.Queue
}
func NewServer() *Server {
return &Server{
connTimeout: 20 * time.Minute,
commandTimeout: 1 * time.Minute,
queue: queue.New(),
}
}
@@ -211,6 +216,7 @@ func (s *Server) serve(l net.Listener) {
tlsConfig: s.tlsConfig,
deadline: time.Now().Add(s.connTimeout),
commandTimeout: s.commandTimeout,
queue: s.queue,
}
go sc.Handle()
}
@@ -244,6 +250,9 @@ type Conn struct {
// When we should close this connection, no matter what.
deadline time.Time
// Queue where we put incoming mails.
queue *queue.Queue
// Time we wait for network operations.
commandTimeout time.Duration
}
@@ -321,6 +330,7 @@ loop:
if err != nil {
tr.LazyPrintf("exiting with error: %v", err)
tr.SetError()
}
}
@@ -396,8 +406,8 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
// Note some servers check (and fail) if we had a previous MAIL command,
// but that's not according to the RFC. We reset the envelope instead.
c.resetEnvelope()
c.mail_from = e.Address
return 250, "You feel like you are being watched"
}
@@ -463,6 +473,18 @@ func (c *Conn) DATA(params string, tr trace.Trace) (code int, msg string) {
tr.LazyPrintf("-> ... %d bytes of data", len(c.data))
// TODO: here is where we queue/send/process the message!
// There are no partial failures here: we put it in the queue, and then if
// individual deliveries fail, we report via email.
// TODO: this should queue, not send, the message.
// TODO: trace this.
msgID, err := c.queue.Put(c.mail_from, c.rcpt_to, c.data)
if err != nil {
tr.LazyPrintf(" error queueing: %v", err)
tr.SetError()
return 554, fmt.Sprintf("Failed to enqueue message: %v", err)
}
tr.LazyPrintf(" ... queued: %q", msgID)
// It is very important that we reset the envelope before returning,
// so clients can send other emails right away without needing to RSET.