Created
July 20, 2016 14:00
-
-
Save natdm/6f40cf5c73550668471945babceb4d55 to your computer and use it in GitHub Desktop.
Explaining how to make DB calls with goroutines and waitgroups.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//GetTransactionsAndLinesForBidder hits the database 3 times. Let's make that fast. | |
func (db *DB) GetTransactionsAndLinesForBidder(bidderID int) ([]BidderTransaction, error) { | |
//Establish a waitgroup. This has 3 functions only. Add, Wait, and Done. You add to the WaitGroup and hit Done when you are | |
// done with a process. It will stop the function at Wait until the WaitGroup is at 0. | |
var wg sync.WaitGroup | |
//Get the transaction 'shell' | |
trans, err := db.GetTransactionsForBidder(bidderID) | |
if err != nil { | |
return trans, err | |
} | |
//Add one to the waitgroup | |
wg.Add(1) | |
//On a separate thread/coroutine/goroutine, go get data. This function sends this off and continues, and does not care about the result yet | |
go func() { | |
//Wait to call 'wg.Done' until this function is over. "Defer" is a beautiful beautiful thing. | |
defer wg.Done() | |
//Do shit. | |
for i, t := range trans { | |
lines, err := db.GetLinesFromTransaction(t.OrderID) | |
if err != nil { | |
log.Errorf("No lines found for OrderID %v. There should always be lines", t.OrderID) | |
//There should be at least one row. | |
} | |
trans[i].Lines = lines | |
} | |
}() | |
//Add another to the WaitGroup | |
wg.Add(1) | |
//Go do shit on another goroutine | |
go func() { | |
//Defer the done call again. | |
defer wg.Done() | |
//Do more shit. | |
for i, t := range trans { | |
details, err := db.GetEventData(t.EventID) | |
if err != nil { | |
log.Errorf("No event data found for event %v.", trans[0].EventID) | |
// Don't stop or return | |
} | |
trans[i].Details = details | |
} | |
}() | |
//Stop this function here and wait until both the goroutines (running at the same time) are done. | |
wg.Wait() | |
//Then finally return | |
return trans, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment