Skip to content

Commit 549316e

Browse files
authored
send gcal reminders in parallel (#339)
1 parent fe26767 commit 549316e

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

gcalbot/gcalbot/reminderscheduler/send.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package reminderscheduler
22

33
import (
4+
"context"
45
"fmt"
56
"time"
67

8+
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
79
"github.com/keybase/managed-bots/gcalbot/gcalbot"
10+
"github.com/keybase/pipeliner"
811
)
912

1013
func (r *ReminderScheduler) sendReminderLoop(shutdownCh chan struct{}) error {
@@ -37,6 +40,10 @@ func (r *ReminderScheduler) sendReminderLoop(shutdownCh chan struct{}) error {
3740

3841
func (r *ReminderScheduler) sendReminders(sendMinute time.Time) {
3942
timestamp := getReminderTimestamp(sendMinute, 0)
43+
var sendTasks []struct {
44+
convID chat1.ConvIDStr
45+
message string
46+
}
4047
r.minuteReminders.ForEachReminderMessageInMinute(timestamp, func(msg *ReminderMessage) {
4148
for duration := range msg.MinuteReminders {
4249
msgTimestamp := getReminderTimestamp(msg.StartTime, duration)
@@ -48,12 +55,17 @@ func (r *ReminderScheduler) sendReminders(sendMinute time.Time) {
4855
} else {
4956
eventSummary = "An event"
5057
}
58+
var message string
5159
if minutesBefore == 0 {
52-
r.ChatEcho(msg.KeybaseConvID, "%s is starting now: %s", eventSummary, msg.MsgContent)
60+
message = fmt.Sprintf("%s is starting now: %s", eventSummary, msg.MsgContent)
5361
} else {
54-
r.ChatEcho(msg.KeybaseConvID, "%s is starting in %s: %s",
62+
message = fmt.Sprintf("%s is starting in %s: %s",
5563
eventSummary, gcalbot.MinutesBeforeString(minutesBefore), msg.MsgContent)
5664
}
65+
sendTasks = append(sendTasks, struct {
66+
convID chat1.ConvIDStr
67+
message string
68+
}{msg.KeybaseConvID, message})
5769
delete(msg.MinuteReminders, duration)
5870
r.stats.Count("sendReminders - reminder")
5971
}
@@ -65,9 +77,26 @@ func (r *ReminderScheduler) sendReminders(sendMinute time.Time) {
6577
}
6678
})
6779
r.minuteReminders.RemoveMinute(timestamp)
80+
81+
const sendWindow = 10
82+
ctx := context.Background()
83+
pipe := pipeliner.NewPipeliner(sendWindow)
84+
worker := func(_ context.Context, i int) error { // nolint:unparam
85+
t := sendTasks[i]
86+
r.ChatEcho(t.convID, "%s", t.message)
87+
return nil
88+
}
89+
for i := range sendTasks {
90+
if err := pipe.WaitForRoom(ctx); err != nil {
91+
break
92+
}
93+
go func() { pipe.CompleteOne(worker(ctx, i)) }()
94+
}
95+
_ = pipe.Flush(ctx)
96+
6897
sendDuration := time.Since(sendMinute)
6998
if sendDuration.Seconds() > 15 {
70-
r.Errorf("sending reminders took %s", sendDuration.String())
99+
r.Errorf("sending %d reminders took %s", len(sendTasks), sendDuration.String())
71100
}
72101
r.stats.Value("sendReminders - duration - seconds", sendDuration.Seconds())
73102
}

gcalbot/gcalbot/schedulescheduler/send.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"golang.org/x/oauth2"
1111

1212
"google.golang.org/api/calendar/v3"
13+
"google.golang.org/api/googleapi"
1314

1415
"github.com/keybase/managed-bots/gcalbot/gcalbot"
1516
)
@@ -131,7 +132,12 @@ func (s *ScheduleScheduler) SendDailyScheduleMessage(sendMinute time.Time, subsc
131132
for index, calendarID := range subscription.CalendarIDs {
132133
cal, err := srv.Calendars.Get(calendarID).Fields("summary").Do()
133134
if err != nil {
134-
s.Errorf("error getting calendar summary from API: %s", err)
135+
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
136+
// Calendar was deleted or user lost access; use ID as display name
137+
s.Debug("calendar no longer accessible (404): %s", calendarID)
138+
} else {
139+
s.Errorf("error getting calendar summary from API: %s", err)
140+
}
135141
calendarSummaries[index] = calendarID // use the cal id if there is an error
136142
} else {
137143
calendarSummaries[index] = cal.Summary

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
1717
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123
1818
github.com/keybase/go-keybase-chat-bot v0.0.0-20260127182354-7367dd3315a3
19+
github.com/keybase/pipeliner v0.0.0-20260107202117-7e0ff0869cf1
1920
github.com/opensearch-project/opensearch-go/v4 v4.5.0
2021
github.com/stathat/go v1.0.0
2122
github.com/stretchr/testify v1.11.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 h1:yg56lYPqh9suJe
100100
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20=
101101
github.com/keybase/go-keybase-chat-bot v0.0.0-20260127182354-7367dd3315a3 h1:0uwBoNFUfi+vqQplGh2md1bak0WYelaoqkjn6hBSwJM=
102102
github.com/keybase/go-keybase-chat-bot v0.0.0-20260127182354-7367dd3315a3/go.mod h1:wl5lBoVNkepL8Hzs7jyqg3GS6U+by4yQeNr7oT0Evt0=
103+
github.com/keybase/pipeliner v0.0.0-20260107202117-7e0ff0869cf1 h1:aqymqcmuSOLTlGuWnfii7odizltdPaLi2hhDCpRwPqs=
104+
github.com/keybase/pipeliner v0.0.0-20260107202117-7e0ff0869cf1/go.mod h1:YT8b13LS9QDe45OyX1BFgXD0BRANHm0xauB+LNfV6WM=
103105
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
104106
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
105107
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=

0 commit comments

Comments
 (0)