Last active
December 20, 2015 22:48
-
-
Save jordanorelli/6207698 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| diff --git a/go/src/hello/hello.go b/go/src/hello/hello.go | |
| index 5f54709..b843e19 100644 | |
| --- a/go/src/hello/hello.go | |
| +++ b/go/src/hello/hello.go | |
| @@ -10,6 +10,7 @@ import ( | |
| "runtime" | |
| "sort" | |
| "strconv" | |
| + "sync" | |
| _ "github.com/go-sql-driver/mysql" | |
| ) | |
| @@ -52,12 +53,15 @@ var ( | |
| updateStatement *sql.Stmt | |
| helloWorldBytes = []byte(helloWorldString) | |
| + db *sql.DB | |
| + queryChan chan (*queryRequest) | |
| ) | |
| func main() { | |
| runtime.GOMAXPROCS(runtime.NumCPU()) | |
| - db, err := sql.Open("mysql", connectionString) | |
| + var err error | |
| + db, err = sql.Open("mysql", connectionString) | |
| if err != nil { | |
| log.Fatalf("Error opening database: %v", err) | |
| } | |
| @@ -75,6 +79,12 @@ func main() { | |
| log.Fatal(err) | |
| } | |
| + queryChan = make(chan *queryRequest) | |
| + numQueryRunners := runtime.NumCPU() * 2 | |
| + for i := 0; i < numQueryRunners; i++ { | |
| + go queryRunner(queryChan) | |
| + } | |
| + | |
| http.HandleFunc("/db", dbHandler) | |
| http.HandleFunc("/queries", queriesHandler) | |
| http.HandleFunc("/json", jsonHandler) | |
| @@ -102,6 +112,38 @@ func dbHandler(w http.ResponseWriter, r *http.Request) { | |
| json.NewEncoder(w).Encode(&world) | |
| } | |
| +type queryRequest struct { | |
| + n int | |
| + wg *sync.WaitGroup | |
| + result World | |
| + err error | |
| +} | |
| + | |
| +func setupQueryRequest(r *queryRequest, wg *sync.WaitGroup) { | |
| + r.n = rand.Intn(worldRowCount) + 1 | |
| + r.wg = wg | |
| +} | |
| + | |
| +func (q *queryRequest) MarshalJSON() ([]byte, error) { | |
| + return json.Marshal(q.result) | |
| +} | |
| + | |
| +func (r *queryRequest) runQuery(stmt *sql.Stmt) { | |
| + defer r.wg.Done() | |
| + r.err = stmt.QueryRow(r.n).Scan(&r.result.Id, &r.result.RandomNumber) | |
| +} | |
| + | |
| +func queryRunner(c chan *queryRequest) { | |
| + stmt, err := db.Prepare(worldSelect) | |
| + if err != nil { | |
| + log.Fatal(err) | |
| + } | |
| + defer stmt.Close() | |
| + for r := range c { | |
| + r.runQuery(stmt) | |
| + } | |
| +} | |
| + | |
| // Test 3: Multiple database queries | |
| func queriesHandler(w http.ResponseWriter, r *http.Request) { | |
| n := 1 | |
| @@ -114,16 +156,23 @@ func queriesHandler(w http.ResponseWriter, r *http.Request) { | |
| return | |
| } | |
| - world := make([]World, n) | |
| + var wg sync.WaitGroup | |
| + queries := make([]queryRequest, n) | |
| + wg.Add(n) | |
| for i := 0; i < n; i++ { | |
| - err := worldStatement.QueryRow(rand.Intn(worldRowCount)+1).Scan(&world[i].Id, &world[ | |
| - if err != nil { | |
| - log.Fatalf("Error scanning world row: %s", err.Error()) | |
| + setupQueryRequest(&queries[i], &wg) | |
| + queryChan <- &queries[i] | |
| + } | |
| + wg.Wait() | |
| + | |
| + for i := range queries { | |
| + if queries[i].err != nil { | |
| + log.Fatalf("Error scanning world row: %d %s", queries[i].n, queries[i].err.Er | |
| } | |
| } | |
| w.Header().Set("Content-Type", "application/json") | |
| - json.NewEncoder(w).Encode(world) | |
| + json.NewEncoder(w).Encode(queries) | |
| } | |
| // Test 4: Fortunes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment