Mercurial > code > home > repos > gcalendarwatch
diff calsync/event_sync.go @ 56:635ff76f867c
WIP: rewrite: process load+sync in parallel between cals; simplify a lot
author | drewp@bigasterisk.com |
---|---|
date | Thu, 05 Sep 2024 13:50:40 -0700 |
parents | 627c815f83bb |
children | 24f662799710 |
line wrap: on
line diff
--- a/calsync/event_sync.go Tue Sep 03 14:50:20 2024 -0700 +++ b/calsync/event_sync.go Thu Sep 05 13:50:40 2024 -0700 @@ -9,46 +9,67 @@ "bigasterisk.com/go/gcalendarwatch/mongoclient" ) -// Runs forever. Applies to all calendars. -func updateMongoEventsToMatchGoogle( - mc *mongoclient.MongoClient, gc *gcalclient.GCalClient) error { - t := time.Now() - eventUpdates := make(chan *gcalclient.FindEventsMessage) +// Each calendar syncs like this: +// 1. Full sync of events taking place between `now-keepHistory` to `now+syncAhead`. +// 2. Garbage-collect all events last-modified before `now-keepHistory` +// 3. Continuous watch of each calendar to catch updates. +func updateMongoEventsToMatchGoogleForever( + mc *mongoclient.MongoClient, + gc *gcalclient.GCalClient, + keepHistory time.Duration, + syncAhead time.Duration) error { + + now := time.Now() + syncStart := now.Add(-keepHistory) + syncEnd := now.Add(syncAhead) + // Note that we could receive updates outside this interval. - updateRoutine(eventUpdates, gc, mc) + cals, err := mc.GetAllCals() + if err != nil { + return err + } + log.Println("syncing events from", len(cals), "calendars") + + readerErr := make(chan error) + for _, cal := range cals { + rd := newCalEventsReader(mc, gc, cal, syncStart, syncEnd) + go func() { + readerErr <- rd.updateForever() + }() + } + return <-readerErr +} - for ev := range eventUpdates { - log.Println("up for ev", ev.CalId) - if ev.Event != nil { - mc.UpsertOneEvent( - convert.MongoEventFromGoogleEvent2( - ev.Event.CalendarUrl, - ev.Event, - /*modSince=*/ t, - ), - ) - } else { - log.Println("cal", ev.CalId, "ready for cleanup") - log.Println("t=", t) - mc.DeleteEventsUpdatedBefore(t) - } +type calEventsReader struct { + mc *mongoclient.MongoClient + gc *gcalclient.GCalClient + cal mongoclient.MongoCal + t1 time.Time + t2 time.Time +} + +func newCalEventsReader(mc *mongoclient.MongoClient, gc *gcalclient.GCalClient, cal mongoclient.MongoCal, t1 time.Time, t2 time.Time) *calEventsReader { + return &calEventsReader{mc, gc, cal, t1, t2} +} + +func (r *calEventsReader) updateForever() error { + + var syncToken string + items, err := r.gc.ListEventsInRange(r.cal, r.t1, r.t2) + if err != nil { + return err } - log.Fatalln("updateMongoEventsToMatchGoogle done??") + for _, item := range items { + r.mc.UpsertOneEvent(convert.MongoEventFromGoogleEvent2(&item.Event, time.Now() /*todo*/)) + syncToken = item.SyncToken + } + + r.mc.DeleteEventsUpdatedBefore(r.cal, r.t1) + + for _, item := range r.gc.ListEventUpdatesForever(syncToken) { + // r.mc.UpsertOneEvent(convert.MongoEventFromGoogleEvent2(item.ev, time.Now()/*todo*/)) + syncToken = item.SyncToken + _ = syncToken + } return nil } - -func updateRoutine( - eventUpdates chan *gcalclient.FindEventsMessage, - gc *gcalclient.GCalClient, - mc *mongoclient.MongoClient, -) { - defer close(eventUpdates) - - t := time.Now() - err := gc.FindEvents(mc, t.AddDate(0, 0, -3), t.AddDate(0, 0, 7), eventUpdates) - if err != nil { - log.Println(err) - return - } - log.Println("updateRoutine done") -}