diff options
Diffstat (limited to 'content/context.article')
-rw-r--r-- | content/context.article | 51 |
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 |