I have a collection of job id's I must request data for. Each job id response could possibly return 3 pages. Once I have all the responses, I am extracting some props and writing it to a csv file.
I'd like to recursively call a function to get this data, should the response meta data indicate it is page 1 of x.
Once I have pages x of x I no longer wish to call that routine and when all routines have finished, I was to progress my application logic.
I am have been looking at go routines and channels as a way of handling this flow.
func (c *Controller) GetBulkJobProps() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
jobs := models.BulkJobListIDs{}
json.NewDecoder(r.Body).Decode(&jobs)
if len(jobs.BulkSendJobs) == 0 {
err := models.Error{}
err.Message = "Missing bulk job id(s)"
utils.SendError(w, 400, err)
return
}
c := make(chan string)
for _, id := range jobs.BulkSendJobs {
go getLink(id, 1, c)
}
for l := range c {
go func(id string) {
if id == "quit" {
close(c)
return
}
getLink(id, 2, c)
}(l)
}
filename := time.Now().Format("02-01-2006_15:04:05")
utils.CreateCSV(filename, csvResponse)
csvResponse = nil
w.Header().Add("Content-Type", "application/json")
utils.SendSuccess(w, nil)
}
}
func getLink(id string, page int, c chan string) {
data := utils.FetchBulkJobProps(id, page)
for _, r := range data.SignatureRequests {
for _, sr := range r.Signatures {
csvResponse = append(csvResponse, []string{r.Title, sr.SignerEmailAddress, sr.StatusCode})
if data.ListInfo.NumPages > data.ListInfo.Page {
c <- id
return
}
c <- "quit"
}
}
}
I was hoping that by ensuring data.ListInfo.NumPages > data.ListInfo.Page
I can assert there is a next page to request, if not I would like to signal my channel to end this particular routine somehow.
I thought maybe by passing c <- "quit"
back into the channel, rather than the id that needs a follow up call, I could signal my function literal to end that routine.
for l := range c {
go func(id string) {
if id == "quit" {
close(c)
return
}
getLink(id, 2, c)
}(l)
}
Instead this appear to crash my app, I believe as I am now sending on a closed channel.