Start learning free

LESSON 121 OF 173 · BACKEND: SPEED

Measure First in Go

Practice

Before you make the shop faster, measure it: otherwise you can't tell whether a change really helped. In this module you measure the work a request does by counting its database queries. A count gives the same answer on every computer, while a time in milliseconds changes with the machine and with whatever else it is doing.

Every handler in the shop asks the database through one of two helpers, runQuery for reads and runExec for writes, so those are the places to count: a wrapper does its job and keeps score on the way. The score lives in a package-level map, which every function in the package can change. Here is the same idea on another value, a counter of visits:

var visits = map[string]int{"count": 0}

app.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
	visits["count"]++
	writeJSON(w, 200, map[string]any{"message": "Hi!", "visits": visits["count"]})
})

To read the count, add a debug route: a tool for you, the developer, not a page for customers. The count only goes up, so read it before and after a request: the difference is what that request cost. Your code must give these answers, in this order:

GET /debug/queries  →  200  {"queries": 0}
GET /products/1  →  200  {"category": "kitchen", "id": 1, "name": "Mug", "price": 12, "stock": 10}
GET /debug/queries  →  200  {"queries": 1}
GET /customers/1/orders  →  200  [{"id": 1, "items": […], …}, {"id": 3, "items": […], …}]
GET /debug/queries  →  200  {"queries": 4}
GET /customers/5/orders  →  200  []
GET /debug/queries  →  200  {"queries": 5}

Customer 1's orders cost 3 queries: one for the orders, then one for the items of each of the 2 orders. Customer 5 has no orders, so only the first query runs. Reading the count is not a query, so it never counts itself.

Your task: add a package variable stats, a map[string]int whose key "queries" starts at 0, make runQuery and runExec add 1 to it every time they run, and register a handler for GET /debug/queries that answers stats as JSON with writeJSON.


Assignment
Follow the Coding Tutorial to count every query in runQuery and runExec and show the count at GET /debug/queries.


Hint
The counting line goes first in runQuery and in runExec, the helpers every handler uses. ++ adds one to the value already in the map.


STEP 1 OF 5
    Ctrl + Enter to check

    Speed Count Queries in Go

    Keep going with Go1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free