102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package queue
|
|
|
|
import (
|
|
"strconv"
|
|
)
|
|
|
|
// Add to queue
|
|
func (q *Queue) Add(id, from, to, data string) error {
|
|
itemkey := acQueueKey + "." + id
|
|
item := map[string]string{
|
|
"attempts": "0",
|
|
"data": data,
|
|
"from": from,
|
|
"to": to,
|
|
"id": id,
|
|
}
|
|
|
|
q.mu.Lock(itemkey)
|
|
defer q.mu.Unlock(itemkey)
|
|
err := q.lp.SetAccountData(itemkey, item)
|
|
if err != nil {
|
|
q.log.Error("cannot enqueue email id=%q: %v", id, err)
|
|
return err
|
|
}
|
|
|
|
q.mu.Lock(acQueueKey)
|
|
defer q.mu.Unlock(acQueueKey)
|
|
queueIndex, err := q.lp.GetAccountData(acQueueKey)
|
|
if err != nil {
|
|
q.log.Error("cannot get queue index: %v", err)
|
|
return err
|
|
}
|
|
queueIndex[id] = itemkey
|
|
err = q.lp.SetAccountData(acQueueKey, queueIndex)
|
|
if err != nil {
|
|
q.log.Error("cannot save queue index: %v", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Remove from queue
|
|
func (q *Queue) Remove(id string) error {
|
|
index, err := q.lp.GetAccountData(acQueueKey)
|
|
if err != nil {
|
|
q.log.Error("cannot get queue index: %v", err)
|
|
return err
|
|
}
|
|
itemkey := index[id]
|
|
if itemkey == "" {
|
|
itemkey = acQueueKey + "." + id
|
|
}
|
|
delete(index, id)
|
|
err = q.lp.SetAccountData(acQueueKey, index)
|
|
if err != nil {
|
|
q.log.Error("cannot update queue index: %v", err)
|
|
return err
|
|
}
|
|
|
|
q.mu.Lock(itemkey)
|
|
defer q.mu.Unlock(itemkey)
|
|
return q.lp.SetAccountData(itemkey, nil)
|
|
}
|
|
|
|
// try to send email
|
|
func (q *Queue) try(itemkey string, maxRetries int) bool {
|
|
q.mu.Lock(itemkey)
|
|
defer q.mu.Unlock(itemkey)
|
|
|
|
item, err := q.lp.GetAccountData(itemkey)
|
|
if err != nil {
|
|
q.log.Error("cannot retrieve a queue item %q: %v", itemkey, err)
|
|
return false
|
|
}
|
|
q.log.Debug("processing queue item %+v", item)
|
|
attempts, err := strconv.Atoi(item["attempts"])
|
|
if err != nil {
|
|
q.log.Error("cannot parse attempts of %q: %v", itemkey, err)
|
|
return false
|
|
}
|
|
if attempts > maxRetries {
|
|
return true
|
|
}
|
|
|
|
err = q.sendmail(item["from"], item["to"], item["data"])
|
|
if err == nil {
|
|
q.log.Debug("email %q from queue was delivered")
|
|
return true
|
|
}
|
|
|
|
q.log.Debug("attempted to deliver email id=%q, retry=%q, but it's not ready yet: %v", item["id"], item["attempts"], err)
|
|
attempts++
|
|
item["attempts"] = strconv.Itoa(attempts)
|
|
err = q.lp.SetAccountData(itemkey, item)
|
|
if err != nil {
|
|
q.log.Error("cannot update attempt count on email %q: %v", itemkey, err)
|
|
}
|
|
|
|
return false
|
|
}
|