Golang / GoLang Production Patterns and Web Standards Interview Questions
How do you implement timeouts for non-HTTP operations like database queries and external calls?
Context-based timeouts apply to any blocking operation — database queries, cache lookups, file operations, and external gRPC calls. The pattern is identical: create a child context with a deadline and pass it to every blocking call.
// Database query with timeout func getUserFromDB(ctx context.Context, db *sql.DB, id int) (*User, error) { // Add query-level timeout (in addition to any HTTP request timeout) ctx, cancel := context.WithTimeout(ctx, 2*time.Second) defer cancel() row := db.QueryRowContext(ctx, "SELECT id, name, email FROM users WHERE id = $1", id) var u User if err := row.Scan(&u.ID, &u.Name, &u.Email); err != nil { if errors.Is(err, context.DeadlineExceeded) { return nil, fmt.Errorf("DB query timed out after 2s: %w", err) } return nil, fmt.Errorf("getUserFromDB: %w", err) } return &u, nil } // Multiple operations with individual timeouts func getUserProfile(ctx context.Context, userID int) (*Profile, error) { // DB: 2s timeout dbCtx, dbCancel := context.WithTimeout(ctx, 2*time.Second) defer dbCancel() user, err := getUserFromDB(dbCtx, db, userID) if err != nil { return nil, err } // Cache: 500ms timeout cacheCtx, cacheCancel := context.WithTimeout(ctx, 500*time.Millisecond) defer cacheCancel() prefs, _ := getPrefsFromCache(cacheCtx, userID) // non-fatal if cache misses // External API: 3s timeout apiCtx, apiCancel := context.WithTimeout(ctx, 3*time.Second) defer apiCancel() avatar, err := fetchAvatarFromCDN(apiCtx, user.AvatarURL) if err != nil { log.Printf("avatar fetch failed (non-fatal): %v", err) } return buildProfile(user, prefs, avatar), nil }
More Related questions...