fix (GODT-597): duplicate send when draft creation takes a long time

This commit is contained in:
James Houlahan
2020-08-17 10:49:56 +02:00
parent 77c6ba381e
commit 35b37c7097
4 changed files with 35 additions and 9 deletions

View File

@ -69,14 +69,31 @@ func (q *sendRecorder) getMessageHash(message *pmapi.Message) string {
return fmt.Sprintf("%x", h.Sum(nil))
}
func (q *sendRecorder) addMessage(hash, messageID string) {
func (q *sendRecorder) addMessage(hash string) {
q.lock.Lock()
defer q.lock.Unlock()
q.deleteExpiredKeys()
q.hashes[hash] = sendRecorderValue{
messageID: messageID,
time: time.Now(),
time: time.Now(),
}
}
func (q *sendRecorder) removeMessage(hash string) {
q.lock.Lock()
defer q.lock.Unlock()
q.deleteExpiredKeys()
delete(q.hashes, hash)
}
func (q *sendRecorder) setMessageID(hash, messageID string) {
q.lock.Lock()
defer q.lock.Unlock()
if val, ok := q.hashes[hash]; ok {
val.messageID = messageID
q.hashes[hash] = val
}
}
@ -89,6 +106,12 @@ func (q *sendRecorder) isSendingOrSent(client messageGetter, hash string) (isSen
if !ok {
return
}
// If we have a value but don't yet have a messageID, we are in the process of uploading the draft.
if value.messageID == "" {
return true, false
}
message, err := client.GetMessage(value.messageID)
// Message could be deleted or there could be an internet issue or whatever,
// so let's assume the message was not sent.
@ -107,7 +130,8 @@ func (q *sendRecorder) isSendingOrSent(client messageGetter, hash string) (isSen
if message.Type == pmapi.MessageTypeSent || message.Type == pmapi.MessageTypeInboxAndSent {
wasSent = true
}
return
return isSending, wasSent
}
func (q *sendRecorder) deleteExpiredKeys() {

View File

@ -365,7 +365,8 @@ func TestSendRecorder_getMessageHash(t *testing.T) {
func TestSendRecorder_isSendingOrSent(t *testing.T) {
q := newSendRecorder()
q.addMessage("hash", "messageID")
q.addMessage("hash")
q.setMessageID("hash", "messageID")
testCases := []struct {
hash string

View File

@ -230,11 +230,13 @@ func (su *smtpUser) Send(from string, to []string, messageReader io.Reader) (err
return nil
}
su.backend.sendRecorder.addMessage(sendRecorderMessageHash)
message, atts, err := su.storeUser.CreateDraft(kr, message, attReaders, attachedPublicKey, attachedPublicKeyName, parentID)
if err != nil {
su.backend.sendRecorder.removeMessage(sendRecorderMessageHash)
return
}
su.backend.sendRecorder.addMessage(sendRecorderMessageHash, message.ID)
su.backend.sendRecorder.setMessageID(sendRecorderMessageHash, message.ID)
// We always have to create a new draft even if there already is one,
// because clients don't necessarily save the draft before sending, which