Remove async SMTP queue

This commit is contained in:
Drew DeVault 2020-11-13 10:33:19 -05:00
parent 0d1cca191b
commit 86579bb478
7 changed files with 7 additions and 148 deletions

View file

@ -78,8 +78,6 @@ func main() {
go e.Start(addr)
s.Queue.Start(context.Background())
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGUSR1, syscall.SIGINT)
@ -98,9 +96,5 @@ func main() {
e.Shutdown(ctx)
cancel()
e.Logger.Print("Waiting for work queues to finish...")
s.Queue.Shutdown()
e.Logger.Print("Shut down.")
s.Close()
}

View file

@ -96,7 +96,6 @@ type mailboxType int
const (
mailboxSent mailboxType = iota
mailboxOutbox mailboxType = iota
mailboxDrafts
)
@ -117,9 +116,6 @@ func getMailboxByType(conn *imapclient.Client, mboxType mailboxType) (*MailboxIn
case mailboxDrafts:
attr = imapspecialuse.Drafts
fallbackNames = []string{"Draft", "Drafts"}
case mailboxOutbox:
attr = ""
fallbackNames = []string{"Outbox"}
}
var attrMatched bool

View file

@ -2,7 +2,6 @@ package alpsbase
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
@ -13,7 +12,6 @@ import (
"strings"
"git.sr.ht/~emersion/alps"
"git.sr.ht/~sircmpwn/dowork"
"github.com/emersion/go-imap"
imapmove "github.com/emersion/go-imap-move"
imapclient "github.com/emersion/go-imap/client"
@ -80,7 +78,6 @@ type IMAPBaseRenderData struct {
Mailboxes []MailboxInfo
Mailbox *MailboxStatus
Inbox *MailboxStatus
Outbox *MailboxStatus
}
type MailboxRenderData struct {
@ -95,7 +92,6 @@ type CategorizedMailboxes struct {
Common struct {
Inbox *MailboxInfo
Drafts *MailboxInfo
Outbox *MailboxInfo
Sent *MailboxInfo
Junk *MailboxInfo
Trash *MailboxInfo
@ -131,11 +127,6 @@ func newIMAPBaseRenderData(ctx *alps.Context,
return err
}
}
if mboxName == "Outbox" {
outbox = active
} else {
outbox, _ = getMailboxStatus(c, "Outbox")
}
return nil
})
if err != nil {
@ -146,7 +137,6 @@ func newIMAPBaseRenderData(ctx *alps.Context,
mmap := map[string]**MailboxInfo{
"INBOX": &categorized.Common.Inbox,
"Drafts": &categorized.Common.Drafts,
"Outbox": &categorized.Common.Outbox,
"Sent": &categorized.Common.Sent,
"Junk": &categorized.Common.Junk,
"Trash": &categorized.Common.Trash,
@ -497,68 +487,9 @@ type composeOptions struct {
// Send message, append it to the Sent mailbox, mark the original message as
// answered
func submitCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOptions) error {
msg.Ref(3)
err := ctx.Session.DoIMAP(func(c *imapclient.Client) error {
// (disregard error, we don't care if Outbox already existed)
c.Create("Outbox")
if _, err := appendMessage(c, msg, mailboxOutbox); err != nil {
return err
}
msg.Unref()
return nil
err := ctx.Session.DoSMTP(func (c *smtp.Client) error {
return sendMessage(c, msg)
})
if err != nil {
return fmt.Errorf("failed to save message to outbox: %v", err)
}
task := work.NewTask(func(_ context.Context) error {
err := ctx.Session.DoSMTP(func (c *smtp.Client) error {
return sendMessage(c, msg)
})
if err != nil {
ctx.Logger().Printf("Error sending email: %v\n", err)
}
return err
}).Retries(5).After(func(_ context.Context, task *work.Task) {
ctx.Logger().Printf("email sent: %v", task.Result())
if task.Result() == nil {
// Remove from outbox
err := ctx.Session.DoIMAP(func(c *imapclient.Client) error {
if err := ensureMailboxSelected(c, "Outbox"); err != nil {
return err
}
uids, err := c.UidSearch(&imap.SearchCriteria{
Header: map[string][]string{
"Message-Id": []string{msg.MessageID},
},
})
if err != nil {
return fmt.Errorf("UID SEARCH failed: %v", err)
}
if len(uids) == 1 {
if err = deleteMessage(c, "Outbox", uids[0]); err != nil {
return err
}
} else {
ctx.Logger().Errorf(
"Unexpectedly found multiple results in outbox for message ID %s",
msg.MessageID)
}
return nil
})
if err != nil {
ctx.Logger().Errorf("Error removing message from outbox: %v", err)
}
} else {
ctx.Logger().Errorf("Message delivery failed with error %v", err)
}
msg.Unref()
})
err = ctx.Server.Queue.Enqueue(task)
if err != nil {
if _, ok := err.(alps.AuthError); ok {
return echo.NewHTTPError(http.StatusForbidden, err)
@ -579,8 +510,6 @@ func submitCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
if _, err := appendMessage(c, msg, mailboxSent); err != nil {
return err
}
msg.Unref()
if draft := options.Draft; draft != nil {
if err := deleteMessage(c, draft.Mailbox, draft.Uid); err != nil {
return err
@ -685,11 +614,9 @@ func handleCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
if attachment == nil {
return fmt.Errorf("Unable to retrieve message attachment %s from session", uuid)
}
msg.Attachments = append(msg.Attachments, &refcountedAttachment{
attachment.File,
attachment.Form,
0,
})
msg.Attachments = append(msg.Attachments,
&formAttachment{attachment.File})
defer attachment.Form.RemoveAll()
}
if saveAsDraft {

View file

@ -53,37 +53,6 @@ func (att *formAttachment) Filename() string {
return att.FileHeader.Filename
}
type refcountedAttachment struct {
*multipart.FileHeader
*multipart.Form
refs int
}
func (att *refcountedAttachment) Open() (io.ReadCloser, error) {
return att.FileHeader.Open()
}
func (att *refcountedAttachment) MIMEType() string {
// TODO: retain params, e.g. "charset"?
t, _, _ := mime.ParseMediaType(att.FileHeader.Header.Get("Content-Type"))
return t
}
func (att *refcountedAttachment) Filename() string {
return att.FileHeader.Filename
}
func (att *refcountedAttachment) Ref(n int) {
att.refs += n
}
func (att *refcountedAttachment) Unref() {
att.refs -= 1
if att.refs == 0 {
att.Form.RemoveAll()
}
}
type imapAttachment struct {
Mailbox string
Uid uint32
@ -211,22 +180,6 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error {
return nil
}
func (msg *OutgoingMessage) Ref(n int) {
for _, a := range msg.Attachments {
if a, ok := a.(*refcountedAttachment); ok {
a.Ref(n)
}
}
}
func (msg *OutgoingMessage) Unref() {
for _, a := range msg.Attachments {
if a, ok := a.(*refcountedAttachment); ok {
a.Unref()
}
}
}
func sendMessage(c *smtp.Client, msg *OutgoingMessage) error {
if err := c.Mail(msg.From, nil); err != nil {
return fmt.Errorf("MAIL FROM failed: %v", err)

View file

@ -10,7 +10,6 @@ import (
"sync"
"time"
"git.sr.ht/~sircmpwn/dowork"
"github.com/fernet/fernet-go"
"github.com/labstack/echo/v4"
)
@ -25,7 +24,6 @@ type Server struct {
e *echo.Echo
Sessions *SessionManager
Options *Options
Queue *work.Queue
mutex sync.RWMutex // used for server reload
plugins []Plugin
@ -68,8 +66,6 @@ func newServer(e *echo.Echo, options *Options) (*Server, error) {
}
s.Sessions = newSessionManager(s.dialIMAP, s.dialSMTP, e.Logger, options.Debug)
s.Queue = work.NewQueue("alps")
return s, nil
}

View file

@ -62,8 +62,8 @@ type Session struct {
}
type Attachment struct {
File *multipart.FileHeader
Form *multipart.Form
File *multipart.FileHeader
Form *multipart.Form
}
func (s *Session) ping() {

View file

@ -7,12 +7,6 @@
{{ .Name }}
{{- end -}}
{{- if .HasAttr "\\HasChildren" }}/{{ end }}
{{ if eq .Name "Outbox" }}
{{ if and (ne .Total -1) (ne .Total 0) }}({{ .Total }} unsent){{ end }}
{{ else }}
{{ if and (ne .Unseen -1) (ne .Unseen 0) }}({{ .Unseen }}){{ end }}
{{ end }}
</a>
{{ else }}
<span class="noselect">
@ -30,7 +24,6 @@
{{ with .CategorizedMailboxes }}
{{ with .Common.Inbox }}{{ template "mbox-link" . }}{{ end }}
{{ with .Common.Drafts }}{{ template "mbox-link" . }}{{ end }}
{{ with .Common.Outbox }}{{ template "mbox-link" . }}{{ end }}
{{ with .Common.Sent }}{{ template "mbox-link" . }}{{ end }}
{{ with .Common.Junk }}{{ template "mbox-link" . }}{{ end }}
{{ with .Common.Trash }}{{ template "mbox-link" . }}{{ end }}