From c2697725ead29c3c108a8e5f7a9f6ab7519ed7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 4 Jun 2023 21:55:50 +0200 Subject: Add new config option to set max number of IMAP connections. Default is 5 (as was the hard-coded value before). Closes issue #98. --- config.yml.example | 2 ++ internal/imap/client.go | 30 ++++++++++++++---------------- internal/imap/imap.go | 6 +++--- main.go | 2 +- pkg/config/config.go | 6 ++++++ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/config.yml.example b/config.yml.example index f235928..7102671 100644 --- a/config.yml.example +++ b/config.yml.example @@ -34,6 +34,8 @@ timeout: 30 # Maximum number of failures allowed before they are reported in normal mode. # By default, failures are only visible in verbose mode. Most feeds tend to suffer from temporary failures. max-failures: 10 +# Maximum number of concurrent IMAP connections opened. +max-imap-connections: 5 # Parts to generate in the resulting emails. # Valid parts are "text" and "html" parts: ["text", "html"] diff --git a/internal/imap/client.go b/internal/imap/client.go index 83903fa..4a0a0d8 100644 --- a/internal/imap/client.go +++ b/internal/imap/client.go @@ -13,8 +13,6 @@ import ( "github.com/Necoro/feed2imap-go/pkg/log" ) -const numberConns = 5 - type connConf struct { host string delimiter string @@ -23,13 +21,13 @@ type connConf struct { type Client struct { connConf - mailboxes *mailboxes - commander *commander - connections [numberConns]*connection - idxCounter int - connChannel chan *connection - connLock sync.Mutex - disconnected bool + mailboxes *mailboxes + commander *commander + connections []*connection + maxConnections int + connChannel chan *connection + connLock sync.Mutex + disconnected bool } var dialer imapClient.Dialer @@ -107,9 +105,7 @@ func (cl *Client) Disconnect() { func (cl *Client) createConnection(c *imapClient.Client) *connection { - cl.idxCounter++ - - if cl.idxCounter >= len(cl.connections) { + if len(cl.connections) == cl.maxConnections { panic("Too many connections") } @@ -121,13 +117,15 @@ func (cl *Client) createConnection(c *imapClient.Client) *connection { c: client, } - cl.connections[cl.idxCounter] = conn + cl.connections = append(cl.connections, conn) return conn } -func newClient() *Client { +func newClient(maxConnections int) *Client { return &Client{ - mailboxes: NewMailboxes(), - connChannel: make(chan *connection, 0), + mailboxes: NewMailboxes(), + connChannel: make(chan *connection, 0), + connections: make([]*connection, 0, maxConnections), + maxConnections: maxConnections, } } diff --git a/internal/imap/imap.go b/internal/imap/imap.go index a44a513..80a37a1 100644 --- a/internal/imap/imap.go +++ b/internal/imap/imap.go @@ -7,10 +7,10 @@ import ( "github.com/Necoro/feed2imap-go/pkg/log" ) -func Connect(url config.Url) (*Client, error) { +func Connect(url config.Url, maxConnections int) (*Client, error) { var err error - client := newClient() + client := newClient(maxConnections) client.host = url.Host defer func() { if err != nil { @@ -41,7 +41,7 @@ func Connect(url config.Url) (*Client, error) { } // the other connections - for i := 1; i < len(client.connections); i++ { + for i := 1; i < client.maxConnections; i++ { 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) diff --git a/main.go b/main.go index e4593be..e535f36 100644 --- a/main.go +++ b/main.go @@ -134,7 +134,7 @@ func run() error { if !dryRun && !buildCache { go func() { var err error - c, err = imap.Connect(cfg.Target) + c, err = imap.Connect(cfg.Target, cfg.MaxConns) imapErr <- err }() diff --git a/pkg/config/config.go b/pkg/config/config.go index 0d2c944..aaf6701 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -23,6 +23,7 @@ type GlobalOptions struct { Target Url `yaml:"target"` Parts []string `yaml:"parts"` MaxFailures int `yaml:"max-failures"` + MaxConns int `yaml:"max-imap-connections"` AutoTarget bool `yaml:"auto-target"` HtmlTemplate string `yaml:"html-template"` TextTemplate string `yaml:"text-template"` @@ -32,6 +33,7 @@ var DefaultGlobalOptions = GlobalOptions{ Cache: "feed.cache", Timeout: 30, MaxFailures: 10, + MaxConns: 5, DefaultEmail: username() + "@" + Hostname(), Target: Url{}, Parts: []string{"text", "html"}, @@ -103,6 +105,10 @@ func (cfg *Config) Validate() error { } } + if cfg.MaxConns < 1 { + return fmt.Errorf("max-imap-connections is '%d', but must be at least 1.", cfg.MaxConns) + } + return nil } -- cgit v1.2.3