aboutsummaryrefslogtreecommitdiff
path: root/content/context.article
diff options
context:
space:
mode:
Diffstat (limited to 'content/context.article')
-rw-r--r--content/context.article51
1 files changed, 26 insertions, 25 deletions
diff --git a/content/context.article b/content/context.article
index 68c7f23..47c320d 100644
--- a/content/context.article
+++ b/content/context.article
@@ -1,10 +1,11 @@
-Go Concurrency Patterns: Context
+# Go Concurrency Patterns: Context
29 Jul 2014
Tags: concurrency, cancelation, cancellation, context
+Summary: In Go servers, each incoming request is handled in its own goroutine. Request handlers often start additional goroutines to access backends such as databases and RPC services. The set of goroutines working on a request typically needs access to request-specific values such as the identity of the end user, authorization tokens, and the request's deadline. When a request is canceled or times out, all the goroutines working on that request should exit quickly so the system can reclaim any resources they are using.
Sameer Ajmani
-* Introduction
+## Introduction
In Go servers, each incoming request is handled in its own goroutine.
Request handlers often start additional goroutines to access backends such as
@@ -20,24 +21,24 @@ At Google, we developed a `context` package that makes it easy to pass
request-scoped values, cancelation signals, and deadlines across API boundaries
to all the goroutines involved in handling a request.
The package is publicly available as
-[[https://golang.org/pkg/context][context]].
+[context](https://golang.org/pkg/context).
This article describes how to use the package and provides a complete working
example.
-* Context
+## Context
The core of the `context` package is the `Context` type:
.code context/interface.go /A Context/,/^}/
(This description is condensed; the
-[[https://golang.org/pkg/context][godoc]] is authoritative.)
+[godoc](https://golang.org/pkg/context) is authoritative.)
The `Done` method returns a channel that acts as a cancelation signal to
functions running on behalf of the `Context`: when the channel is closed, the
functions should abandon their work and return.
The `Err` method returns an error indicating why the `Context` was canceled.
-The [[/pipelines][Pipelines and Cancelation]] article discusses the `Done`
+The [Pipelines and Cancelation](/pipelines) article discusses the `Done`
channel idiom in more detail.
A `Context` does _not_ have a `Cancel` method for the same reason the `Done`
@@ -59,7 +60,7 @@ Code may also use a deadline to set timeouts for I/O operations.
`Value` allows a `Context` to carry request-scoped data.
That data must be safe for simultaneous use by multiple goroutines.
-** Derived contexts
+### Derived contexts
The `context` package provides functions to _derive_ new `Context` values from
existing ones.
@@ -87,24 +88,24 @@ replicas.
The best way to see how to use the `context` package is through a worked
example.
-* Example: Google Web Search
+## Example: Google Web Search
Our example is an HTTP server that handles URLs like
`/search?q=golang&timeout=1s` by forwarding the query "golang" to the
-[[https://developers.google.com/web-search/docs/][Google Web Search API]] and
+[Google Web Search API](https://developers.google.com/web-search/docs/) and
rendering the results.
The `timeout` parameter tells the server to cancel the request after that
duration elapses.
The code is split across three packages:
-- [[context/server/server.go][server]] provides the `main` function and the handler for `/search`.
-- [[context/userip/userip.go][userip]] provides functions for extracting a user IP address from a request and associating it with a `Context`.
-- [[context/google/google.go][google]] provides the `Search` function for sending a query to Google.
+ - [server](context/server/server.go) provides the `main` function and the handler for `/search`.
+ - [userip](context/userip/userip.go) provides functions for extracting a user IP address from a request and associating it with a `Context`.
+ - [google](context/google/google.go) provides the `Search` function for sending a query to Google.
-** The server program
+### The server program
-The [[context/server/server.go][server]] program handles requests like
+The [server](context/server/server.go) program handles requests like
`/search?q=golang` by serving the first few Google search results for `golang`.
It registers `handleSearch` to handle the `/search` endpoint.
The handler creates an initial `Context` called `ctx` and arranges for it to be
@@ -129,9 +130,9 @@ If the search succeeds, the handler renders the results:
.code context/server/server.go /resultsTemplate/,/}$/
-** Package userip
+### Package userip
-The [[context/userip/userip.go][userip]] package provides functions for
+The [userip](context/userip/userip.go) package provides functions for
extracting a user IP address from a request and associating it with a `Context`.
A `Context` provides a key-value mapping, where the keys and values are both of
type `interface{}`.
@@ -157,10 +158,10 @@ a value of this type as the context key:
.code context/userip/userip.go /func FromContext/,/}/
-** Package google
+### Package google
-The [[context/google/google.go][google.Search]] function makes an HTTP request
-to the [[https://developers.google.com/web-search/docs/][Google Web Search API]]
+The [google.Search](context/google/google.go) function makes an HTTP request
+to the [Google Web Search API](https://developers.google.com/web-search/docs/)
and parses the JSON-encoded result.
It accepts a `Context` parameter `ctx` and returns immediately if `ctx.Done` is
closed while the request is in flight.
@@ -182,7 +183,7 @@ It cancels the request if `ctx.Done` is closed before the goroutine exits:
.code context/google/google.go /func httpDo/,/^}/
-* Adapting code for Contexts
+## Adapting code for Contexts
Many server frameworks provide packages and types for carrying request-scoped
values.
@@ -190,23 +191,23 @@ We can define new implementations of the `Context` interface to bridge between
code using existing frameworks and code that expects a `Context` parameter.
For example, Gorilla's
-[[http://www.gorillatoolkit.org/pkg/context][github.com/gorilla/context]]
+[github.com/gorilla/context](http://www.gorillatoolkit.org/pkg/context)
package allows handlers to associate data with incoming requests by providing a
mapping from HTTP requests to key-value pairs.
-In [[context/gorilla/gorilla.go][gorilla.go]], we provide a `Context`
+In [gorilla.go](context/gorilla/gorilla.go), we provide a `Context`
implementation whose `Value` method returns the values associated with a
specific HTTP request in the Gorilla package.
Other packages have provided cancelation support similar to `Context`.
-For example, [[https://godoc.org/gopkg.in/tomb.v2][Tomb]] provides a `Kill`
+For example, [Tomb](https://godoc.org/gopkg.in/tomb.v2) provides a `Kill`
method that signals cancelation by closing a `Dying` channel.
`Tomb` also provides methods to wait for those goroutines to exit, similar to
`sync.WaitGroup`.
-In [[context/tomb/tomb.go][tomb.go]], we provide a `Context` implementation that
+In [tomb.go](context/tomb/tomb.go), we provide a `Context` implementation that
is canceled when either its parent `Context` is canceled or a provided `Tomb` is
killed.
-* Conclusion
+## Conclusion
At Google, we require that Go programmers pass a `Context` parameter as the
first argument to every function on the call path between incoming and outgoing