What is Context?
In Go, context.Context is an
interface which defined in
package context that carries
deadlines, cancellation signals, and request-scoped values across API
boundaries and between goroutines.
Incoming requests to a HTTP server creates a Context, and outgoing calls
to servers accept a Context. The chain of function calls between them
MUST propagate the Context(This is developer's responsibility)
Usage of Context Interface:
1. Cancellation signals: Cancel work when a client disconnects or a
timeout expires
2. Deadlines: Set deadlines for operations (e.g:
DB query must finish in 5 seconds)
3. Request-scoped values: Pass request-scoped data (e.g., user IDs,
authentication tokens) through a call chain
go provided Context Interface
|
|
How Context is provided in Go?
http.Server creates request with context (r.Context()). You can:
- Ignore it: and find problems listed here
- Or can handle and pass to the function (as shown below)
func AddLead(db *sql.DB, w http.ResponseWriter, r *http.Request) {
a := r.Context()
createLead(db, a) // You can pass context downstream
}
func createLead(db *sql.DB, ctx context.Context) {
query := `
INSERT INTO leads (name, email, phone, whatsapp)
VALUES ($1, $2, $3, $4,)
RETURNING id;`
// Add timeout: query must finish in 5 seconds
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// Do DB query with context
err := db.QueryRowContext(ctx, query, ...).Scan(&id)
}
Problems without Context
Database Operations
1. DB write path without Context can hang when:
- DB is slow (network issue, lock): INSERT Query blocks for minutes,
your HTTP handlerblocks, frontend client waits
- Frontend Client disconnects: and now work needed to be done still DB
INSERT Query still runs, wastes DB connection, CPU
- DB server crashes: INSERT/SELECT Query hangs forever, no timeout
- Server gets 1000 requests: 1000 DB connections are opened and blocked,
server becomes unresponsive
| Problematic Code | Solution |
|---|---|
|
|
2. DB Read path with Context can hang
- When DB is slow (network issue, lock) due to no timeout set on DB read
path
- DB server crashes: SELECT Query hangs forever, no timeout
2. Server keeps waiting, while client disconnected
HTTP Client connects and then disconnects (within 5 seconds)
Go's `http.Server` spawns 1 Go Routine per request to handle every
client. request. Without Context Http Server will waiting for 180+
seconds, when at 180 seconds TCP keepalive timer fires(if set) then it
close the connection. This is server resource wastage.
// WITHOUT context timeout
client → HTTP request → server starts DB query → client waits 5s → client timeouts →
server STILL runs DB query for 175 more seconds → wastes DB connection, CPU
// WITH context timeout:
client → HTTP request → server sets 5s timeout → client waits 5s → client timeouts →
server's DB query is CANCELLED immediately → frees DB connection, CPU