milestone/07 #144

Merged
fuzzy merged 18 commits from milestone/07 into main 2026-06-30 12:42:47 +00:00
Owner
No description provided.
- Log every poll cycle with current lastUID
- Log 'no new messages' when poll finds nothing
- Log each message received in the main loop
- Increase PollResult channel buffer from 1 to 10
- Remove default case that silently dropped poll results
- Add /config.yaml to .gitignore to prevent credential leaks
Template strings from config files can contain literal escape sequences
that YAML single-quoted strings preserve. Replace \n, \t, and \\
with actual newline, tab, and backslash characters before compiling.
- Add state_file config option (default: 9biff.state)
- Save uid_validity and last_uid as JSON after each poll
- Load saved state on startup when UID validity matches
- Fall back to server-reported last UID on first run or validity change
- Add alert_gap config field (duration, default 0s = no gap)
- Pause between each message write in main loop
- Applies to both batched and non-batched paths
- Replace time.Sleep with context-aware select so Ctrl+C works during gap
- Move initial poll out of PollLoop goroutine to after 9P writers connect
- Extract processMessages to dedupe batch/non-batch message handling
- Initial poll runs synchronously in main goroutine with proper ordering
- Add batch_template config field (default: 'You have mail: {{.Count}} new messages')
- RenderBatch method on Engine for batch notifications
- BatchData struct with Count and Messages fields
- Batcher flush now renders one batch message instead of individual writes
- writeBatch helper writes pre-formatted string to all endpoints
Previously state was saved outside the lock and only when messages were
found. This could cause lastUID corruption from races, and no-save on
empty polls meant restarts could re-deliver already-seen messages.
Now saveStateLocked runs under m.mu on every path including early returns.
Previously Select() fetched the last message by sequence number, which
may not have the highest UID when deletions have occurred. Now uses
UID SEARCH 1:* to find the actual highest UID in the mailbox.
go-imap's UidFetch may drop messages with Uid==0 from the channel
(ErrUnhandled). When the server omits the UID fetch attribute, msg.Uid
is 0, maxUID stays 0, lastUID stays 0, and every poll re-finds all
messages. Fixed by setting lastUID directly from the UID search results
and removing FetchUid from the items list.
The re-SELECT in FetchNew could return a different UidValidity than the
initial Select, causing lastUID to reset to 0 and re-find all messages
every poll cycle. FetchNew now uses the already-selected mailbox state.
State saves use m.uidValidity consistently. Added debug logging for
state load/save operations.
Log state loads/saves, mailbox initialization, and UID search results
at INFO level so we can see exactly what last_uid and uid_validity values
are being set and used during polling.
The IMAP server returns UID 1 for search 'UID 2:*' instead of empty.
Now fetch all UIDs and filter client-side by comparing against lastUID.
When running for the first time (no state file, last_uid=0), treat all
messages as unseen. Only filter uid > last_uid when we have existing state.
fix: use loadedState flag instead of lastUID>0 for first-run detection
Some checks failed
Test and Release / test (pull_request) Successful in 1m22s
Test and Release / lint (pull_request) Failing after 1m31s
96a0916c9b
fuzzy scheduled this pull request to auto merge when all checks succeed 2026-06-30 12:31:47 +00:00
fuzzy force-pushed milestone/07 from 96a0916c9b
Some checks failed
Test and Release / test (pull_request) Successful in 1m22s
Test and Release / lint (pull_request) Failing after 1m31s
to 31d8db5924
All checks were successful
Test and Release / test (pull_request) Successful in 49s
Test and Release / lint (pull_request) Successful in 2m32s
2026-06-30 12:39:23 +00:00
Compare
fuzzy merged commit 31d8db5924 into main 2026-06-30 12:42:47 +00:00
fuzzy deleted branch milestone/07 2026-06-30 12:42:48 +00:00
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
thwap/9biff!144
No description provided.