Skip to content

Commit

Permalink
fix(GODT-1615): Fix too many SQL variables error
Browse files Browse the repository at this point in the history
Perform paged loading of snapshot state from the database to avoid
SQL error.

This patch also adds an utility to to fill the database with many
messages and invoke `Flush()` after they have all been submitted.

Testing large mailboxes can cause the CI to timeout, specially on
windows (>10 min), therefore the test is added as a benchmark instead.
  • Loading branch information
LBeernaertProton committed Jul 5, 2022
1 parent 68d9cc3 commit bc89d58
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
23 changes: 18 additions & 5 deletions internal/backend/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,24 @@ func newSnapshot(ctx context.Context, state *State, mbox *ent.Mailbox) (*snapsho
messages: newMsgList(),
}

msgUIDs, err := mbox.QueryUIDs().
WithMessage(func(query *ent.MessageQuery) { query.WithFlags() }).
All(ctx)
if err != nil {
return nil, err
var msgUIDs []*ent.UID

const limit = 16000

for offset := 0; ; offset += limit {
list, err := mbox.QueryUIDs().
WithMessage(func(query *ent.MessageQuery) { query.WithFlags() }).Offset(offset).Limit(limit).
All(ctx)

if err != nil {
return nil, err
}

if len(list) == 0 {
break
}

msgUIDs = append(msgUIDs, list...)
}

for _, msgUID := range msgUIDs {
Expand Down
20 changes: 20 additions & 0 deletions tests/benchmark_big_mailbox_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tests

import (
"fmt"
"testing"
)

func BenchmarkBigMailboxStatus(b *testing.B) {
b.Run("status", func(b *testing.B) {
runOneToOneTestWithAuth(b, defaultServerOptions(b), func(c *testConnection, s *testSession) {
mboxID := s.mailboxCreated("user", []string{"mbox"})

ids := s.batchMessageCreated("user", mboxID, 32515, func(n int) ([]byte, []string) {
return []byte(fmt.Sprintf(`To: %[email protected]`, n)), []string{}
})

c.Cf(`A001 STATUS %v (MESSAGES)`, "mbox").Sx(fmt.Sprintf(`MESSAGES %v`, len(ids))).OK(`A001`)
})
})
}
25 changes: 25 additions & 0 deletions tests/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,31 @@ func (s *testSession) messageCreated(user, mailboxID string, literal []byte, fla
return messageID
}

func (s *testSession) batchMessageCreated(user string, mailboxID string, count int, createMessage func(int) ([]byte, []string)) []string {
var messageIDs []string

for i := 0; i < count; i++ {
messageID := utils.NewRandomMessageID()

literal, flags := createMessage(i)

require.NoError(s.tb, s.conns[s.userIDs[user]].MessageCreated(
imap.Message{
ID: messageID,
Flags: imap.NewFlagSetFromSlice(flags),
Date: time.Now(),
},
literal,
[]string{mailboxID},
))

messageIDs = append(messageIDs, messageID)
}
s.conns[s.userIDs[user]].Flush()

return messageIDs
}

func (s *testSession) messageCreatedFromFile(user, mailboxID, path string, flags ...string) string {
literal, err := os.ReadFile(path)
require.NoError(s.tb, err)
Expand Down

0 comments on commit bc89d58

Please sign in to comment.