imap: add debouncer to the idler
Add a debouncer to the idle mode. Avoid unnecessary idling when another job arrives within a certain time frame. For example, the ui sends three messages to the worker at the same time when we open a message (FlagMessage, FetchMessageBodyPart, and the FetchMessageHeaders). The debouncer prevents the unnecessary entering and leaving of the idle mode between those messages. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
e5b339702a
commit
b92efe4cd9
|
@ -45,7 +45,10 @@ func (w *IMAPWorker) handleConfigure(msg *types.Configure) error {
|
||||||
|
|
||||||
w.config.user = u.User
|
w.config.user = u.User
|
||||||
w.config.folders = msg.Config.Folders
|
w.config.folders = msg.Config.Folders
|
||||||
|
|
||||||
w.config.idle_timeout = 10 * time.Second
|
w.config.idle_timeout = 10 * time.Second
|
||||||
|
w.config.idle_debounce = 10 * time.Millisecond
|
||||||
|
|
||||||
w.config.connection_timeout = 30 * time.Second
|
w.config.connection_timeout = 30 * time.Second
|
||||||
w.config.keepalive_period = 0 * time.Second
|
w.config.keepalive_period = 0 * time.Second
|
||||||
w.config.keepalive_probes = 3
|
w.config.keepalive_probes = 3
|
||||||
|
@ -63,6 +66,14 @@ func (w *IMAPWorker) handleConfigure(msg *types.Configure) error {
|
||||||
value, err)
|
value, err)
|
||||||
}
|
}
|
||||||
w.config.idle_timeout = val
|
w.config.idle_timeout = val
|
||||||
|
case "idle-debounce":
|
||||||
|
val, err := time.ParseDuration(value)
|
||||||
|
if err != nil || val < 0 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"invalid idle-debounce value %v: %v",
|
||||||
|
value, err)
|
||||||
|
}
|
||||||
|
w.config.idle_debounce = val
|
||||||
case "reconnect-maxwait":
|
case "reconnect-maxwait":
|
||||||
val, err := time.ParseDuration(value)
|
val, err := time.ParseDuration(value)
|
||||||
if err != nil || val < 0 {
|
if err != nil || val < 0 {
|
||||||
|
|
|
@ -25,6 +25,7 @@ type idler struct {
|
||||||
config imapConfig
|
config imapConfig
|
||||||
client *imapClient
|
client *imapClient
|
||||||
worker *types.Worker
|
worker *types.Worker
|
||||||
|
last time.Time
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
done chan error
|
done chan error
|
||||||
waiting bool
|
waiting bool
|
||||||
|
@ -63,8 +64,16 @@ func (i *idler) isReady() bool {
|
||||||
func (i *idler) Start() {
|
func (i *idler) Start() {
|
||||||
if i.isReady() {
|
if i.isReady() {
|
||||||
i.stop = make(chan struct{})
|
i.stop = make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer logging.PanicHandler()
|
defer logging.PanicHandler()
|
||||||
|
select {
|
||||||
|
case <-i.stop:
|
||||||
|
// debounce idle
|
||||||
|
i.log("=>(idle) [debounce]")
|
||||||
|
i.done <- nil
|
||||||
|
case <-time.After(i.config.idle_debounce):
|
||||||
|
// enter idle mode
|
||||||
i.idleing = true
|
i.idleing = true
|
||||||
i.log("=>(idle)")
|
i.log("=>(idle)")
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
@ -75,8 +84,11 @@ func (i *idler) Start() {
|
||||||
})
|
})
|
||||||
i.idleing = false
|
i.idleing = false
|
||||||
i.done <- err
|
i.done <- err
|
||||||
i.log("elapsed ideling time:", time.Since(now))
|
i.log("elapsed idle time:",
|
||||||
|
time.Since(now))
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
} else if i.isWaiting() {
|
} else if i.isWaiting() {
|
||||||
i.log("not started: wait for idle to exit")
|
i.log("not started: wait for idle to exit")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,6 +43,7 @@ type imapConfig struct {
|
||||||
folders []string
|
folders []string
|
||||||
oauthBearer lib.OAuthBearer
|
oauthBearer lib.OAuthBearer
|
||||||
idle_timeout time.Duration
|
idle_timeout time.Duration
|
||||||
|
idle_debounce time.Duration
|
||||||
reconnect_maxwait time.Duration
|
reconnect_maxwait time.Duration
|
||||||
// tcp connection parameters
|
// tcp connection parameters
|
||||||
connection_timeout time.Duration
|
connection_timeout time.Duration
|
||||||
|
|
Loading…
Reference in New Issue