Remove async SMTP queue
This commit is contained in:
parent
0d1cca191b
commit
86579bb478
7 changed files with 7 additions and 148 deletions
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 }}
|
||||
|
|
Loading…
Reference in a new issue