fix: IDLE not waking on new messages, add --debug flag #8

Closed
heiko wants to merge 70 commits from fix/idle into master
Owner

Summary

  • Fix IDLE never waking on EXISTS: register UnilateralDataHandler that signals a channel to break IDLE immediately when new messages arrive
  • Add --debug=imap flag for IMAP wire protocol dump (stderr)
  • Add --debug=scan flag for scan lifecycle logging (search results, IDLE wake events, reconnect attempts)

Root cause

The go-imap v2 IdleCommand.Wait() only returns when Close() is called. EXISTS notifications fire through UnilateralDataHandler.Mailbox, but no handler was registered — notifications were silently discarded. The IDLE loop only checked for new messages every 28 minutes (timeout).

Test plan

  • go test ./... passes
  • golangci-lint run clean
  • Run with --debug=imap,scan, deliver a message, verify IDLE breaks and message is processed immediately
## Summary - Fix IDLE never waking on EXISTS: register UnilateralDataHandler that signals a channel to break IDLE immediately when new messages arrive - Add `--debug=imap` flag for IMAP wire protocol dump (stderr) - Add `--debug=scan` flag for scan lifecycle logging (search results, IDLE wake events, reconnect attempts) ## Root cause The go-imap v2 `IdleCommand.Wait()` only returns when `Close()` is called. EXISTS notifications fire through `UnilateralDataHandler.Mailbox`, but no handler was registered — notifications were silently discarded. The IDLE loop only checked for new messages every 28 minutes (timeout). ## Test plan - [x] `go test ./...` passes - [x] `golangci-lint run` clean - [ ] Run with `--debug=imap,scan`, deliver a message, verify IDLE breaks and message is processed immediately
The go-imap v2 IDLE implementation requires an explicit Close() call to
exit — EXISTS notifications were silently discarded because no
UnilateralDataHandler was registered. Register a Mailbox handler that
signals a buffered channel on EXISTS; idleOnce selects on both the
timeout and this channel to break IDLE immediately.

Also adds --debug=imap (wire protocol dump) and --debug=scan (scan
lifecycle logging) for diagnosing IMAP issues.
Author
Owner

Tests pass for this branch with:

CGO_ENABLED=0 GOCACHE=/tmp/go-build-pr8 go test ./...

One small thing I’d tighten before merge: --debug silently ignores unknown values. For example, --debug=imapx currently behaves like debug is disabled. It would be better to fail fast with a clear error for unsupported debug channels, while accepting the current imap and scan values.

Tests pass for this branch with: CGO_ENABLED=0 GOCACHE=/tmp/go-build-pr8 go test ./... One small thing I’d tighten before merge: --debug silently ignores unknown values. For example, --debug=imapx currently behaves like debug is disabled. It would be better to fail fast with a clear error for unsupported debug channels, while accepting the current imap and scan values.
heiko closed this pull request 2026-05-11 18:45:24 +02:00

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
IUS/xr-invoiced!8
No description provided.