Repository: go
Issue: all: document uses of context.Background by APIs
Labels: Documentation,Proposal,Proposal-Accepted

# Objective
Amend all non-root [`context.Background()`](https://golang.org/pkg/context/#Background) use in the standard distribution to [`context.TODO()`](https://golang.org/pkg/context/#TODO).  

A central purpose is to have the Go source code serve as a prime example of correct context usage to newcomers and better teach users how to retrofit support after-the-fact.

# Definitions
A classical program’s roots are: [func main](https://golang.org/ref/spec#Program_execution), [test functions](https://golang.org/pkg/testing), and [func init](https://golang.org/ref/spec#Package_initialization).  These are effectively the entrypoints where user code can begin outside of other top-level variable declarations.

# Background
The context API [debuted in 2014](https://blog.golang.org/context) and became part of the standard distribution in [release 1.7](https://golang.org/doc/go1.7).

Many APIs that were context-capable but predated the API retrofitted support with the introduction of function names suffixed with “Context” to indicate “this is the context-capable variant”.  An example is [`(*sql.DB).QueryRow`](https://golang.org/pkg/database/sql/#DB.QueryRow) and [`(*sql.DB).QueryRowContext`](https://golang.org/pkg/database/sql/#DB.QueryRowContext).  This is largely due to [Go 1 compatibility guarantee](https://golang.org/doc/go1compat), which meant backward compatibility could not be broken.

The problem is users do not always respect the guidance associated with `context.Background`

> Background returns a non-nil, empty Context. It is never canceled, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.

and instead use `context.Background` deep in call graphs instead of propagating a context from outward to the proper scope where the value is required.  Where this is infeasible, `context.TODO` is precisely the tool to use. To wit:

> TODO returns a non-nil, empty Context. Code should use context.TODO when it's unclear which Context to use or it is not yet available (because the surrounding function has not yet been extended to accept a Context parameter).

If we amend the standard distribution, it effectively provides a solid affirmative use for `context.TODO` and helps reify the design counsel.  This has several additional knock-on benefits for encouraging design of [production-correct and -scalable APIs](https://sre.google/sre-book/handling-overload/), which requires systems to correctly and predictably handle load and interruption (e.g., to avoid unbounded memory usage).

# Scale and Requirements
Replacement of the default context should introduce no behavior delta for existing users.  Further, it should not regress performance.  Neither of these should be a problem in practice with production code.  It would be extremely unconventional for an end-user developer or infrastructure developer to care about context identity.
```go
// This is almost entirely inconceivable.
if ctx == context.Background() {
```

There are approximately 53 non-test, non-vendor usages of `context.Background` in `/usr/local/go` for `go version go1.15.8 linux/amd64`:

```shell
$ grep -r 'context.Background()' | grep -v -E '(testdata|^vendor|_test\.go)' | wc -l
53
```

Outside of request-scoped contexts (no pun-intended) like `package http` used to initiate client calls or handle external requests, the above litmus test for root contexts likely fails for most of the standard distribution.  About eight `context.Background` calls are probably excusable.

# Proposed Solution
Audit calls to `context.Background` and swap them to `context.TODO` where they clearly are not root operations nor could under any real rubric count as one.  A litmus test:

If any transitive function calls made by the following roots should be cancelable, `context.TODO` is more appropriate:

```go
type Server struct {
  db *sql.DB
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  ctx, cancel := context.WithCancel(r.Context())  // implied that middleware may deadline
  defer cancel()

  rows, err := s.DB.Query(q)  // extremely like the user would want this to be canceable
}
```

Internally [`(*sql.DB).Query`](https://golang.org/pkg/database/sql/#DB.Query) calls [`(*sql.DB).QueryContext`](https://golang.org/pkg/database/sql/#DB.QueryContext) with `context.Background`.   A user wanting cancellation would use `(*sql.DB).QueryContext`.

Or in the case of gRPC (with code supra):

```go
func (s *Server) Echo(ctx context.Context, req *echopb.EchoRequest) (*echopb.EchoResponse, error) {
  
  // store echo queries in an audit log to satisfy the auditors
  rows, err := s.DB.Query(q)  // extremely like the user would want this to be canceable
}
```

To be sure, `context.TODO` in the code above won’t miraculously become cancelable (that's not the point).  But a curious Gopher may compare the two implementations (e.g., `(*sql.DB).Query` and `(*sql.DB).QueryContext`), see `context.TODO`, and then be prompted to consider how these semantics should fit into the design.  And this is not about preventing or deprecating non-context-correct older public API variants in the standard distribution (though this has been something I’ve thought about a lot over the years).

# Alternatives Considered
While this defect report/proposal was motivated by incorrect code in user code, which is classically the purview of static analysis of something to report, I think it would be best if Go took its own medicine here by applying the advice correctly itself.  ;)  Appeals to authority happen, and the Go source tree has a semi-canonical status in the mindset of the user base.