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")
-}