Merge branch 'context1'

This commit is contained in:
Mark McGranaghan 2020-01-04 09:51:27 -08:00
commit acc5c0365c
8 changed files with 259 additions and 3 deletions

View File

@ -68,6 +68,7 @@ Command-Line Subcommands
Environment Variables
HTTP Clients
HTTP Servers
Context
Spawning Processes
Exec'ing Processes
Signals

View File

@ -0,0 +1,44 @@
// In the previous example we looked at setting up a simple
// [HTTP server](http-servers). HTTP servers are useful for
// demonstrating the usage of `context.Context` for
// controlling cancellation.
package main
import (
"fmt"
"net/http"
"time"
)
func hello(w http.ResponseWriter, req *http.Request) {
// A `context.Context` is created for each request by
// the `net/http` machinery, and is available with
// the `Context()` method.
ctx := req.Context()
fmt.Println("server: hello handler started")
defer fmt.Println("server: hello handler ended")
// Wait for 3 seconds before sending a reply to the
// client. This could simulate some work the server is
// doing. While working, keep an eye on the context's
// `Done()` channel for a signal that we should cancel
// the work and return as soon as possible.
select {
case <-time.After(10 * time.Second):
fmt.Fprintf(w, "hello\n")
case <-ctx.Done():
err := ctx.Err()
fmt.Println("server:", err)
internalError := http.StatusInternalServerError
http.Error(w, err.Error(), internalError)
}
}
func main() {
// As before, we register our handler on the "/hello"
// route, and start serving.
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8090", nil)
}

View File

@ -0,0 +1,2 @@
a899a68d131b0f8cf3ae846ef728877d2407d219
9fUzFC2uyFk

View File

@ -0,0 +1,11 @@
# Run the server in the background.
$ go run context-in-http-servers.go &
# Simulate a client request to `/hello`, hitting
# Ctrl+C shortly after starting to signal
# cancellation.
$ curl localhost:8090/hello
server: hello handler started
^C
server: context canceled
server: hello handler ended

196
public/context generated Normal file
View File

@ -0,0 +1,196 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go by Example: Context</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'http-servers';
}
if (e.key == "ArrowRight") {
window.location.href = 'spawning-processes';
}
}
</script>
<body>
<div class="example" id="context">
<h2><a href="./">Go by Example</a>: Context</h2>
<table>
<tr>
<td class="docs">
<p>In the previous example we looked at setting up a simple
<a href="http-servers">HTTP server</a>. HTTP servers are useful for
demonstrating the usage of <code>context.Context</code> for
controlling cancellation.</p>
</td>
<td class="code leading">
<a href="http://play.golang.org/p/9fUzFC2uyFk"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;net/http&quot;</span>
<span class="s">&quot;time&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">func</span> <span class="nx">hello</span><span class="p">(</span><span class="nx">w</span> <span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span> <span class="nx">req</span> <span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>A <code>context.Context</code> is created for each request by
the <code>net/http</code> machinery, and is available with
the <code>Context()</code> method.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">ctx</span> <span class="o">:=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">Context</span><span class="p">()</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;server: hello handler started&quot;</span><span class="p">)</span>
<span class="k">defer</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;server: hello handler ended&quot;</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Wait for 3 seconds before sending a reply to the
client. This could simulate some work the server is
doing. While working, keep an eye on the context&rsquo;s
<code>Done()</code> channel for a signal that we should cancel
the work and return as soon as possible.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="k">select</span> <span class="p">{</span>
<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">time</span><span class="p">.</span><span class="nx">After</span><span class="p">(</span><span class="mi">10</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">):</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Fprintf</span><span class="p">(</span><span class="nx">w</span><span class="p">,</span> <span class="s">&quot;hello\n&quot;</span><span class="p">)</span>
<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">Done</span><span class="p">():</span>
<span class="nx">err</span> <span class="o">:=</span> <span class="nx">ctx</span><span class="p">.</span><span class="nx">Err</span><span class="p">()</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;server:&quot;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="nx">internalError</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nx">StatusInternalServerError</span>
<span class="nx">http</span><span class="p">.</span><span class="nx">Error</span><span class="p">(</span><span class="nx">w</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">Error</span><span class="p">(),</span> <span class="nx">internalError</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>As before, we register our handler on the &ldquo;/hello&rdquo;
route, and start serving.</p>
</td>
<td class="code">
<div class="highlight"><pre> <span class="nx">http</span><span class="p">.</span><span class="nx">HandleFunc</span><span class="p">(</span><span class="s">&quot;/hello&quot;</span><span class="p">,</span> <span class="nx">hello</span><span class="p">)</span>
<span class="nx">http</span><span class="p">.</span><span class="nx">ListenAndServe</span><span class="p">(</span><span class="s">&quot;:8090&quot;</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
<p>Run the server in the background.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">$</span> go run context-in-http-servers.go <span class="p">&amp;</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Simulate a client request to <code>/hello</code>, hitting
Ctrl+C shortly after starting to signal
cancellation.</p>
</td>
<td class="code">
<div class="highlight"><pre><span class="gp">$</span> curl localhost:8090/hello
<span class="go">server: hello handler started</span>
<span class="go">^C</span>
<span class="go">server: context canceled</span>
<span class="go">server: hello handler ended</span>
</pre></div>
</td>
</tr>
</table>
<p class="next">
Next example: <a href="spawning-processes">Spawning Processes</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/context">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"net/http\"\u000A \"time\"\u000A)\u000A');codeLines.push('func hello(w http.ResponseWriter, req *http.Request) {\u000A');codeLines.push(' ctx := req.Context()\u000A fmt.Println(\"server: hello handler started\")\u000A defer fmt.Println(\"server: hello handler ended\")\u000A');codeLines.push(' select {\u000A case \x3C-time.After(10 * time.Second):\u000A fmt.Fprintf(w, \"hello\\n\")\u000A case \x3C-ctx.Done():\u000A err := ctx.Err()\u000A fmt.Println(\"server:\", err)\u000A internalError := http.StatusInternalServerError\u000A http.Error(w, err.Error(), internalError)\u000A }\u000A}\u000A');codeLines.push('func main() {\u000A');codeLines.push(' http.HandleFunc(\"/hello\", hello)\u000A http.ListenAndServe(\":8090\", nil)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>

4
public/http-servers generated
View File

@ -14,7 +14,7 @@
if (e.key == "ArrowRight") {
window.location.href = 'spawning-processes';
window.location.href = 'context';
}
}
@ -201,7 +201,7 @@ router we&rsquo;ve just set up.</p>
<p class="next">
Next example: <a href="spawning-processes">Spawning Processes</a>.
Next example: <a href="context">Context</a>.
</p>
<p class="footer">

2
public/index.html generated
View File

@ -163,6 +163,8 @@
<li><a href="http-servers">HTTP Servers</a></li>
<li><a href="context">Context</a></li>
<li><a href="spawning-processes">Spawning Processes</a></li>
<li><a href="execing-processes">Exec'ing Processes</a></li>

View File

@ -9,7 +9,7 @@
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'http-servers';
window.location.href = 'context';
}