Noob question here. I have a script that takes in a list of usernames and turns on the vacation responder for them in gmail. I'm not actually sure if my code is using concurrency the way it's meant to be used. I.e. did I call go in the right area? Or am I supposed to do it somewhere else (e.g. in one of the for loops in processVacationResponders)? Would it be better if I write it in a producer/consumer pattern or would this good be enough?
I ran this against 2000 test users but it took about 14 min. Not sure if my code is the bottleneck or if maybe the rpcs I'm using are just slow. On the bright side, its a hell of lot faster than the python script (10min / 100 users 😮 ) I have that does the same thing.
main()
c := make(chan userVacationResponderSettings, len(users))
go processVacationResponders(ctx, users, c)
failedUsers := []string{}
for updatedSetting := range c {
if updatedSetting.err != nil {
fmt.Printf("failed to update for %q: %v\n", updatedSetting.email, updatedSetting.err)
failedUsers = append(failedUsers, updatedSetting.email)
continue
}
if updatedSetting.settings == nil {
continue
}
... // printing out stuff
}
if len(failedUsers) > 0 {
fmt.Printf("some updates failed. affected users: %q\n", failedUsers)
}
fmt.Printf("Finished processing in %v\n", time.Since(startTime))
processVacationResponders()
func processVacationResponders(ctx context.Context, users []userVacationResponderSettings, userResponseChannel chan userVacationResponderSettings) {
for _, user := range users {
updatedSettings, err := updateVacationResponder(ctx, user)
if err != nil {
userResponseChannel <- userVacationResponderSettings{email: user.email, err: err}
}
userResponseChannel <- userVacationResponderSettings{email: user.email, settings: updatedSettings}
}
close(userResponseChannel)
}
updateVacationResponder()
func updateVacationResponder(ctx context.Context, user userVacationResponderSettings) (*gmail.VacationSettings, error) {
gmailClient, err := createGmailClient(ctx, user.email)
if err != nil {
return nil, err
}
settings, err := gmailClient.Users.Settings.UpdateVacation(user.email, user.settings).Do()
if err != nil {
return nil, err
}
return settings, err
}