Uh oh!
There was an error while loading. Please reload this page.
Bound the Google Calendar initial backfill to a year and a day - #369
Merged
Conversation
Moves mapWithConcurrency out of the Gmail mail module into a new connectors/google/src/concurrency.ts, re-exported from gmail-api.ts for existing callers. This lets other product modules within the Google connector (e.g. calendar) reuse the same bounded-concurrency helper without importing from the mail module.
… modules" This reverts commit 81840b3.
The comment on SyncState.phase claimed the quick pass front-loads only non-recurring events and that the full pass is what picks up long-running recurring masters "excluded by the quick pass's timeMin". That is wrong. Google does not apply timeMin to recurring masters: verified against a live calendar, a FREQ=YEARLY master whose first instance was in 1980 and a FREQ=WEEKLY master whose RRULE UNTIL had already passed were both returned by a timeMin=now listing. Only non-recurring events are bounded by timeMin, so the quick pass already surfaces upcoming recurring meetings and the full pass exists for past one-off events and the nextSyncToken. Also notes that this is Google-specific and must not be generalised to Microsoft Graph, whose $filter on start/dateTime is a literal comparison against the series master's own first start.
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two changes to the Google Calendar connector's initial sync, one behavioural and one a
correction to a comment that was actively misleading.
Bound the initial backfill to a year and a day
calendarHistoryFloor()returned Jan 1 of two calendar years ago — between 366 and 730 daysback depending on when in the year a connection was made. It now returns a fixed 366 days,
extracted as
CALENDAR_HISTORY_DAYS.A year and a day is chosen deliberately: it is the smallest window that always contains an
annual event, so yearly birthdays and anniversaries stay in scope.
This should not change what a user ends up with. The platform already drops initial-sync
non-recurring items that fall outside the connection's history window, and that window is at
most a year — so the connector was fetching and transmitting events the platform then
discarded. Recurring events are exempt from that filter and are unaffected, for the reason
described below. The practical effect is a shorter backfill: the full pass walks roughly a
third as much history on a connection made late in the calendar year.
Incidentally, the new implementation is also DST-safe. The previous one used
setFullYear/setMonth/setHours, which operate in local machine time; the replacement isepoch-millisecond arithmetic.
Correct what the quick pass actually returns
The comment on
SyncState.phaseclaimed the quick pass (timeMin = now) front-loads onlynon-recurring events, and that the full pass is what "picks up long-running recurring
masters excluded by the quick pass's
timeMin".That is wrong, and it matters — it invites the conclusion that recurring meetings do not
appear until a multi-year history walk completes.
Tested against the Calendar API,
timeMindoes not filter recurring masters at all. AFREQ=YEARLYmaster whose first instance was in 1980, and aFREQ=WEEKLYmaster whoseRRULEUNTILhad already passed, were both returned by atimeMin=nowlisting withsingleEventsunset. Only non-recurring events are bounded bytimeMin.So the quick pass already surfaces upcoming recurring meetings, and the full pass exists to
import past one-off events and to establish the
nextSyncTokenthat incremental syncs reuse.The comment now says this, with the evidence.
It also carries an explicit warning not to generalise the behaviour to Outlook: Microsoft
Graph's
$filter=start/dateTime ge …is a literal comparison against the series master's ownfirst start, which genuinely does exclude a long-running master. The two providers differ, and
the Outlook connector's equivalent comment is left as it was.
Testing
pnpm buildand the full connector suite (20 files, 378 tests) pass. Two new tests pin the366-day value exactly and confirm an event dated one year ago stays inside the window.