From 4f112c16dfac61deb128b48e9d516f78ab55fc95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 28 Feb 2021 13:22:17 +0100 Subject: Start IMAP connections in the background and use them on the go --- internal/imap/client.go | 24 ++++++++++++++++-------- internal/imap/commando.go | 6 +++--- internal/imap/imap.go | 12 +++++++----- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/internal/imap/client.go b/internal/imap/client.go index 783acf6..c916a64 100644 --- a/internal/imap/client.go +++ b/internal/imap/client.go @@ -1,6 +1,8 @@ package imap import ( + "sync/atomic" + uidplus "github.com/emersion/go-imap-uidplus" imapClient "github.com/emersion/go-imap/client" @@ -17,15 +19,17 @@ type connConf struct { type Client struct { connConf - mailboxes *mailboxes - commander *commander - connections [numberConns]*connection - nextFreeIndex int + mailboxes *mailboxes + commander *commander + connections [numberConns]*connection + idxCounter int32 + connChannel chan *connection } func (cl *Client) Disconnect() { if cl != nil { cl.stopCommander() + close(cl.connChannel) connected := false for _, conn := range cl.connections { @@ -39,7 +43,9 @@ func (cl *Client) Disconnect() { } func (cl *Client) createConnection(c *imapClient.Client) *connection { - if cl.nextFreeIndex >= len(cl.connections) { + nextIndex := int(atomic.AddInt32(&cl.idxCounter, 1)) - 1 + + if nextIndex >= len(cl.connections) { panic("Too many connections") } @@ -51,12 +57,14 @@ func (cl *Client) createConnection(c *imapClient.Client) *connection { c: client, } - cl.connections[cl.nextFreeIndex] = conn - cl.nextFreeIndex++ + cl.connections[nextIndex] = conn return conn } func NewClient() *Client { - return &Client{mailboxes: NewMailboxes()} + return &Client{ + mailboxes: NewMailboxes(), + connChannel: make(chan *connection, 0), + } } diff --git a/internal/imap/commando.go b/internal/imap/commando.go index 1ba4ed3..2edbc58 100644 --- a/internal/imap/commando.go +++ b/internal/imap/commando.go @@ -50,11 +50,11 @@ func (cl *Client) startCommander() { cl.commander = &commander{cl, pipe, done} - for _, conn := range cl.connections { - if conn != nil { + go func() { + for conn := range cl.connChannel { go executioner(conn, pipe, done) } - } + }() } func (cl *Client) stopCommander() { diff --git a/internal/imap/imap.go b/internal/imap/imap.go index 369d4b4..20713a4 100644 --- a/internal/imap/imap.go +++ b/internal/imap/imap.go @@ -48,6 +48,7 @@ func (cl *Client) connect(url config.Url) (*connection, error) { return nil, fmt.Errorf("login to %s: %w", url.Host, err) } + cl.connChannel <- conn return conn, nil } @@ -61,6 +62,7 @@ func Connect(url config.Url) (*Client, error) { client.Disconnect() } }() + client.startCommander() var conn *connection // the main connection if conn, err = client.connect(url); err != nil { @@ -87,12 +89,12 @@ func Connect(url config.Url) (*Client, error) { // the other connections for i := 1; i < len(client.connections); i++ { - if _, err := client.connect(url); err != nil { // explicitly new var 'err', b/c these are now harmless - log.Warnf("connecting #%d: %s", i, err) - } + go func(id int) { + if _, err := client.connect(url); err != nil { // explicitly new var 'err', b/c these are now harmless + log.Warnf("connecting #%d: %s", id, err) + } + }(i) } - client.startCommander() - return client, nil } -- cgit v1.2.3