code: func readConfigCron(c *router.Context) {
  	rc := requestContext(*c)
  	projectsToVisit := map[string]bool{}
  
  	// Visit all projects in the catalog.
  	ctx, _ := context.WithTimeout(rc.Context, 150*time.Second)
  	projects, err := globalCatalog.GetAllProjects(ctx)
  	if err != nil {
  		rc.err(err, "Failed to grab a list of project IDs from catalog")
  		return
  	}
  	for _, id := range projects {
  		projectsToVisit[id] = true
  	}
  
  	// Also visit all registered projects that do not show up in the catalog
  	// listing anymore. It will unregister all jobs belonging to them.
  	existing, err := globalEngine.GetAllProjects(rc.Context)
  	if err != nil {
  		rc.err(err, "Failed to grab a list of project IDs from datastore")
  		return
  	}
  	for _, id := range existing {
  		projectsToVisit[id] = true
  	}
  
  	// Handle each project in its own task to avoid "bad" projects (e.g. ones with
  	// lots of jobs) to slow down "good" ones.
  	tasks := make([]*tq.Task, 0, len(projectsToVisit))
  	for projectID := range projectsToVisit {
  		tasks = append(tasks, &tq.Task{
  			Payload: &internal.ReadProjectConfigTask{ProjectId: projectID},
  		})
  	}
  	if err = globalDispatcher.AddTask(rc.Context, tasks...); err != nil {
  		rc.err(err, "Failed to add tasks to task queue")
  	} else {
  		rc.ok()
  	}
  }
docs: // readConfigCron grabs a list of projects from the catalog and datastore and
  // dispatches task queue tasks to update each project's cron jobs.