~blamar/+junk/openstack-api-arrrg

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/web/howto/web-in-60/asynchronous.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Asynchronous Responses</title>
 
4
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Asynchronous Responses</h1>
 
9
    <div class="toc"><ol/></div>
 
10
    <div class="content">
 
11
<span/>
 
12
 
 
13
<p>In all of the previous examples, the resource examples presented generated
 
14
responses immediately. One of the features of prime interest of Twisted Web,
 
15
though, is the ability to generate a response over a longer period of time while
 
16
leaving the server free to respond to other requests. In other words,
 
17
asynchronously. In this installment, we'll write a resource like this.</p>
 
18
 
 
19
<p>A resource that generates a response asynchronously looks like one that
 
20
generates a response synchronously in many ways. The same base class, <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.resource.Resource.html" title="twisted.web.resource.Resource">Resource</a></code>, is used either way; the
 
21
same render methods are used. There are three basic differences, though.</p>
 
22
 
 
23
<p>First, instead of returning the string which will be used as the body of the
 
24
response, the resource uses <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.http.Request.write.html" title="twisted.web.http.Request.write">Request.write</a></code>. This method can be called
 
25
repeatedly. Each call appends another string to the response body. Second, when
 
26
the entire response body has been passed to <code>Request.write</code>, the
 
27
application must call <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.http.Request.finish.html" title="twisted.web.http.Request.finish">Request.finish</a></code>. As you might expect from the
 
28
name, this ends the response. Finally, in order to make Twisted Web not end the
 
29
response as soon as the render method returns, the render method must return
 
30
<code>NOT_DONE_YET</code>. Consider this example:</p>
 
31
 
 
32
<pre class="python"><p class="py-linenumber"> 1
 
33
 2
 
34
 3
 
35
 4
 
36
 5
 
37
 6
 
38
 7
 
39
 8
 
40
 9
 
41
10
 
42
11
 
43
12
 
44
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">resource</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Resource</span>
 
45
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">server</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">NOT_DONE_YET</span>
 
46
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
47
 
 
48
<span class="py-src-keyword">class</span> <span class="py-src-identifier">DelayedResource</span>(<span class="py-src-parameter">Resource</span>):
 
49
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_delayedRender</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
50
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;Sorry to keep you waiting.&quot;</span>)
 
51
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
 
52
 
 
53
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
54
        <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">5</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">_delayedRender</span>, <span class="py-src-variable">request</span>)
 
55
        <span class="py-src-keyword">return</span> <span class="py-src-variable">NOT_DONE_YET</span>
 
56
</pre>
 
57
 
 
58
<p>If you're not familiar with reactor.<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorTime.callLater.html" title="twisted.internet.interfaces.IReactorTime.callLater">callLater</a></code>, all you really
 
59
need to know about it to understand this example is that the above usage of it
 
60
arranges to have <code>self._delayedRender(request)</code> run about 5 seconds
 
61
after <code>callLater</code> is invoked from this render method and that it
 
62
returns immediately.</p>
 
63
 
 
64
<p>All three of the elements mentioned earlier can be seen in this example. The
 
65
resource uses <code>Request.write</code> to set the response body. It uses
 
66
<code>Request.finish</code> after the entire body has been specified (all with
 
67
just one call to write in this case). Lastly, it returns
 
68
<code>NOT_DONE_YET</code> from its render method. So there you have it,
 
69
asynchronous rendering with Twisted Web.</p>
 
70
 
 
71
<p>Here's a complete rpy script based on this resource class (see the <a href="rpy-scripts.html" shape="rect">previous example</a> if you need a reminder about rpy
 
72
scripts):</p>
 
73
 
 
74
<pre class="python"><p class="py-linenumber"> 1
 
75
 2
 
76
 3
 
77
 4
 
78
 5
 
79
 6
 
80
 7
 
81
 8
 
82
 9
 
83
10
 
84
11
 
85
12
 
86
13
 
87
14
 
88
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">resource</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Resource</span>
 
89
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">server</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">NOT_DONE_YET</span>
 
90
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
91
 
 
92
<span class="py-src-keyword">class</span> <span class="py-src-identifier">DelayedResource</span>(<span class="py-src-parameter">Resource</span>):
 
93
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_delayedRender</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
94
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;Sorry to keep you waiting.&quot;</span>)
 
95
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
 
96
 
 
97
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
98
        <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">5</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">_delayedRender</span>, <span class="py-src-variable">request</span>)
 
99
        <span class="py-src-keyword">return</span> <span class="py-src-variable">NOT_DONE_YET</span>
 
100
 
 
101
<span class="py-src-variable">resource</span> = <span class="py-src-variable">DelayedResource</span>()
 
102
</pre>
 
103
 
 
104
<p>Drop this source into a <code>.rpy</code> file and fire up a server using
 
105
<code>twistd -n web --path /directory/containing/script/.</code> You'll see that
 
106
loading the page takes 5 seconds. If you try to load a second before the first
 
107
completes, it will also take 5 seconds from the time you request it (but it
 
108
won't be delayed by any other outstanding requests).</p>
 
109
 
 
110
<p>Something else to consider when generating responses asynchronously is that
 
111
the client may not wait around to get the response to its
 
112
request. A <a href="interrupted.html" shape="rect">subsequent example</a> demonstrates how
 
113
to detect that the client has abandoned the request and that the server
 
114
shouldn't bother to finish generating its response.</p>
 
115
 
 
116
</div>
 
117
 
 
118
    <p><a href="../index.html">Index</a></p>
 
119
    <span class="version">Version: 10.0.0</span>
 
120
  </body>
 
121
</html>
 
 
b'\\ No newline at end of file'