diff --git a/daemon/handler.go b/daemon/handler.go index de2e73c..2c59fb5 100644 --- a/daemon/handler.go +++ b/daemon/handler.go @@ -11,6 +11,15 @@ import ( "github.com/floatpane/matcha/daemonrpc" ) +// Per-handler timeouts. fetchTimeout covers reads against the upstream IMAP +// provider, which can return large bodies and so are given more headroom. +// mutateTimeout covers state-changing operations and folder listings, which +// are bounded by IMAP command latency rather than payload size. +const ( + fetchTimeout = 60 * time.Second + mutateTimeout = 30 * time.Second +) + func (d *Daemon) handleRequest(conn *daemonrpc.Conn, req *daemonrpc.Request) { switch req.Method { case daemonrpc.MethodPing: @@ -117,7 +126,7 @@ func (d *Daemon) handleFetchEmails(conn *daemonrpc.Conn, req *daemonrpc.Request) return } - ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), fetchTimeout) defer cancel() emails, err := p.FetchEmails(ctx, params.Folder, params.Limit, params.Offset) @@ -142,7 +151,7 @@ func (d *Daemon) handleFetchEmailBody(conn *daemonrpc.Conn, req *daemonrpc.Reque return } - ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), fetchTimeout) defer cancel() body, attachments, err := p.FetchEmailBody(ctx, params.Folder, params.UID) @@ -181,7 +190,7 @@ func (d *Daemon) handleDeleteEmails(conn *daemonrpc.Conn, req *daemonrpc.Request return } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), mutateTimeout) defer cancel() if err := p.DeleteEmails(ctx, params.Folder, params.UIDs); err != nil { @@ -204,7 +213,7 @@ func (d *Daemon) handleArchiveEmails(conn *daemonrpc.Conn, req *daemonrpc.Reques return } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), mutateTimeout) defer cancel() if err := p.ArchiveEmails(ctx, params.Folder, params.UIDs); err != nil { @@ -227,7 +236,7 @@ func (d *Daemon) handleMoveEmails(conn *daemonrpc.Conn, req *daemonrpc.Request) return } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), mutateTimeout) defer cancel() if err := p.MoveEmails(ctx, params.UIDs, params.SourceFolder, params.DestFolder); err != nil { @@ -250,7 +259,7 @@ func (d *Daemon) handleMarkRead(conn *daemonrpc.Conn, req *daemonrpc.Request) { return } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), mutateTimeout) defer cancel() // MarkAsRead only supports one UID at a time in the Provider interface. @@ -275,7 +284,7 @@ func (d *Daemon) handleFetchFolders(conn *daemonrpc.Conn, req *daemonrpc.Request return } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), mutateTimeout) defer cancel() folders, err := p.FetchFolders(ctx) @@ -306,7 +315,7 @@ func (d *Daemon) handleRefreshFolder(conn *daemonrpc.Conn, req *daemonrpc.Reques Folder: params.Folder, }) - ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), fetchTimeout) defer cancel() emails, err := p.FetchEmails(ctx, params.Folder, 50, 0)