<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>AmvTek blog</title><link href="/blog/" rel="alternate"></link><link href="/blog/feeds/tags/twisted.atom.xml" rel="self"></link><id>/blog/</id><updated>2014-08-01T00:00:00+03:00</updated><entry><title>Extending coverage of the Python serializers benchmark</title><link href="/blog/posts/2014/Aug/01/extending-coverage-of-the-python-serializers-benchmark/" rel="alternate"></link><updated>2014-08-01T00:00:00+03:00</updated><author><name>AmvTek developers</name></author><id>tag:,2014-08-01:blog/posts/2014/Aug/01/extending-coverage-of-the-python-serializers-benchmark/</id><summary type="html">&lt;p&gt;Our &lt;a class="reference external" href="/blog/posts/2014/Jul/12/comparing-python-performance-of-protobufthrift-serialization/"&gt;previous attend&lt;/a&gt; to compare performances of &lt;strong&gt;Python&lt;/strong&gt; implementations for
&lt;strong&gt;protocol buffers&lt;/strong&gt; and &lt;strong&gt;thrift&lt;/strong&gt; serializations has generated interesting
feedback and suggestions. The main request we received was to try to broaden the
coverage of the previous &lt;a class="reference external" href="https://github.com/amvtek/PySerializers"&gt;benchmark&lt;/a&gt; so as to cover the full range of available&amp;nbsp;options&amp;#8230;&lt;/p&gt;
&lt;p&gt;We are not there yet, but the &lt;a class="reference external" href="https://github.com/amvtek/PySerializers"&gt;benchmark&lt;/a&gt; now allows comparing &lt;strong&gt;5&lt;/strong&gt; differents
frameworks&amp;nbsp;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://developers.google.com/protocol-buffers/"&gt;protocol&amp;nbsp;buffers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://thrift.apache.org/"&gt;thrift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://kentonv.github.io/capnproto/index.html"&gt;capnp proto&lt;/a&gt; (using the &lt;a class="reference external" href="http://jparyani.github.io/pycapnp/"&gt;pycapnp&lt;/a&gt;&amp;nbsp;package)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://json.org/"&gt;json&lt;/a&gt; (standard library&amp;nbsp;package)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://msgpack.org/"&gt;msgpack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="comparing-apples-with-oranges"&gt;
&lt;h2&gt;Comparing apples with&amp;nbsp;oranges&lt;/h2&gt;
&lt;p&gt;Following our &lt;a class="reference external" href="/blog/posts/2014/Jul/12/comparing-python-performance-of-protobufthrift-serialization/"&gt;previous post&lt;/a&gt;, several persons suggested us to have a look at
the &lt;a class="reference external" href="http://kentonv.github.io/capnproto/index.html"&gt;capnp proto&lt;/a&gt; serialization system which is very similar in principle to
thrift and protocol buffers we compared earlier. This similarity allowed us to
get them covered by the previous benchmark in no time, and at first capnp proto
performance looked &lt;strong&gt;astonishingly good&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We refrained to publish such results however, as something was not looking
correct. If we were to believe what was reported, capnp deserialization time
was not depending upon the size or type of the messages to be processed.
Assuming we had misunderstood how to use the pycapnp extension package we were
leveraging, we contacted Jason Paryani who supports it to ask if he could
suggest&amp;nbsp;anything.&lt;/p&gt;
&lt;p&gt;Jason explained us that our results were not surprising him as with capnp &lt;em&gt;real
deserialization&lt;/em&gt; will take place only when message inner content is accessed.
Jason also observed that our previous approach to time serialization was
probably favoring capnp irrealistically as part of the serialization happens
when the message content is&amp;nbsp;set.&lt;/p&gt;
&lt;p&gt;In short, to allow a &lt;em&gt;fair comparison&lt;/em&gt; in between the different frameworks we
wanted to cover and not be fooled by implementation choices made by library
developers, Jason advised to revise our benchmarking approach replacing&amp;nbsp;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;serialize by construct &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt;&amp;nbsp;serialize&lt;/li&gt;
&lt;li&gt;deserialize by deserialize &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt;&amp;nbsp;traverse&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The new approach is probably not a very good one if one want to establish the
&lt;strong&gt;absolute&lt;/strong&gt; performance of a single framework. For example, the full traversal
requirement will unnecessarily harm the deserialization performance figure for
json or msgpack library which deliver fully deserialized dictionaries in one&amp;nbsp;shot.&lt;/p&gt;
&lt;p&gt;We believe however that by having each benchmark performs same duties we render
meaningfull comparisons possibles. We invit however any interested individual
to review current &lt;a class="reference external" href="https://github.com/amvtek/PySerializers"&gt;benchmark&lt;/a&gt; and let us know what could be done to improve
&lt;strong&gt;fairness&lt;/strong&gt; of the comparisons we are trying to&amp;nbsp;make.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="results-overview"&gt;
&lt;h2&gt;Results&amp;nbsp;Overview&lt;/h2&gt;
&lt;p&gt;You may run the benchmarks on your side and send us the results for publication
on the GitHub project. The machines we are relying on are low end one&amp;#8230;&amp;nbsp;:)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/amvtek/PySerializers/blob/master/results/linux_ubuntu-trusty_32b.rst"&gt;linux 32 bits&amp;nbsp;results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/amvtek/PySerializers/blob/master/results/linux_ubuntu-trusty_64b.rst"&gt;linux 64 bits&amp;nbsp;results&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The two kids of the block are &lt;a class="reference external" href="https://thrift.apache.org/"&gt;thrift&lt;/a&gt; and the new entrant &lt;a class="reference external" href="http://msgpack.org/"&gt;msgpack&lt;/a&gt;. There
is no point in trying to departage those &lt;strong&gt;2 winners&lt;/strong&gt; as they are not playing in
the same category (schema versus schemaless&amp;nbsp;systems&amp;#8230;).&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="twisted"></category><category term="serialization"></category></entry><entry><title>Comparing Python performance of Protobuf/Thrift serialization…</title><link href="/blog/posts/2014/Jul/12/comparing-python-performance-of-protobufthrift-serialization/" rel="alternate"></link><updated>2014-07-12T00:00:00+03:00</updated><author><name>AmvTek developers</name></author><id>tag:,2014-07-12:blog/posts/2014/Jul/12/comparing-python-performance-of-protobufthrift-serialization/</id><summary type="html">&lt;p&gt;When in need to get two software processes to exchange datas, some sort of
protocol is necessary to define how to encode/decode the datas to be
transported. A large number of serialization formats are available (json, xml,
&lt;span class="caps"&gt;ASN&lt;/span&gt;.1&amp;#8230;) so as to tackle the &lt;em&gt;cross process/cross programming language&lt;/em&gt; datas
encoding problem and Python provides a large number of libraries to leverage&amp;nbsp;them&amp;#8230;&lt;/p&gt;
&lt;p&gt;What distinguishes the solution provided by &lt;a class="reference external" href="https://developers.google.com/protocol-buffers/"&gt;protocol buffers&lt;/a&gt; or &lt;a class="reference external" href="https://thrift.apache.org/"&gt;thrift&lt;/a&gt; is
the need to describe the datas to be exchanged in a central schema file written
using an &lt;strong&gt;easy to read&lt;/strong&gt; idl language. Such schema file is then &lt;em&gt;compiled&lt;/em&gt; so
as to provide data representation for a certain programming language. Not all
problems will benefit from this approach, but when developping services that
needs to be accessed by clients written in different programming languages ( eg
Objective C, Java&amp;#8230;) we have found that relying on a well defined schema file
allows to save a lot of&amp;nbsp;time.&lt;/p&gt;
&lt;div class="section" id="the-need-for-benchmarking"&gt;
&lt;h2&gt;The need for&amp;nbsp;benchmarking&lt;/h2&gt;
&lt;p&gt;We write a large part of our &lt;strong&gt;server side&lt;/strong&gt; code using Python and some of the
projects we support are accessed mainly by &lt;em&gt;native&lt;/em&gt; clients over &lt;span class="caps"&gt;TCP&lt;/span&gt; or &lt;span class="caps"&gt;UDP&lt;/span&gt;.
Over the years we moved gradually from our home grown custom serialization
solution built on top of Python &lt;a class="reference external" href="https://docs.python.org/2/library/struct.html"&gt;struct module&lt;/a&gt; to protocol&amp;nbsp;buffer&amp;#8230;&lt;/p&gt;
&lt;p&gt;The move to protocol buffer allowed us to cut down development time required to
support new types of client to a minimum. We also realized how the reliance of a
central schema was valuable in that everybody can vizualize what the datas&amp;nbsp;are.&lt;/p&gt;
&lt;p&gt;One thing however we are regretting from the previous home grown solution are
the performances, and &lt;strong&gt;at the server&lt;/strong&gt; performances matter tremendously even
more if you are using an asynchronous networking framework like &lt;a class="reference external" href="https://twistedmatrix.com/trac/"&gt;twisted&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a long while we reinssured ourselves observing that a google supported
extension module was available, and that deploying it, would allow us to
accelerate serialization/deserialization by a factor &lt;strong&gt;10&lt;/strong&gt; at least. Deploying
such extension module was delayed till reaching stagging development phase,
because it is quite cumbersome to do so. You need to build things from source
and manage some environment variables in your server processes, to force the use
of the implementation it&amp;nbsp;provides.&lt;/p&gt;
&lt;p&gt;Once we activated the protobuf extension module on our stagging server we
started to observe random crashes of the server processes. It took us time to
understand that those crashes were related to the use of such extension module.
Well, we should not have underestimated the fact that Google was labelling this
extension module as experimental, but here again we assumed that Google playing
in a different category than the rest of us they were probably referring to some
pretty advanced usecases&amp;nbsp;:(&lt;/p&gt;
&lt;p&gt;After all those hurdles, we realized that selecting the proper serialization
technology for your projects is a decision that shall not be taken lightly.
Thrift provides an obvious alternative to google protocol buffer, but how does
its Python implementation performs ? They exist extensive performance benchmarks
of &lt;a class="reference external" href="https://github.com/eishay/jvm-serializers"&gt;java serialization&lt;/a&gt; frameworks, but we found nothing similar for&amp;nbsp;Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-benchmark"&gt;
&lt;h2&gt;The&amp;nbsp;benchmark&lt;/h2&gt;
&lt;p&gt;We have published on GitHub, what we consider to be a good basis to compare the
various serialization frameworks which one may want to leverage. The repository
for the project can be &lt;a class="reference external" href="https://github.com/amvtek/PbThriftBenchmark"&gt;reached here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The benchmark for now compares the performances of protobuf and thrift
serializations for messages defined in the &lt;a class="reference external" href="https://github.com/amvtek/PbThriftBenchmark/blob/master/idl/StuffToTest.proto"&gt;StuffTotest schema&lt;/a&gt; . We welcome
suggestions to extend such reference schema so as to explore performances
variations more in the details or external help so as to cover more
serialization&amp;nbsp;frameworks&amp;#8230;&lt;/p&gt;
&lt;div class="section" id="preliminary-results"&gt;
&lt;h3&gt;Preliminary&amp;nbsp;results&lt;/h3&gt;
&lt;p&gt;We have published on GitHub a &lt;a class="reference external" href="https://github.com/amvtek/PbThriftBenchmark/blob/master/results.rst"&gt;result run&lt;/a&gt; obtained on a low end development
machine. If we consider performance to be the average in between serialization
and deserialization time for a certain message of the schema, Thrift&amp;nbsp;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;outperforms protocol buffers in 75% of the&amp;nbsp;cases.&lt;/li&gt;
&lt;li&gt;is &lt;strong&gt;stable&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;is much easier to deploy (pip install thrift and you are&amp;nbsp;done&amp;#8230;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So there is currently a &lt;strong&gt;clear winner&lt;/strong&gt; to this benchmark. We will be happy to
rerun it so as to validate that things have&amp;nbsp;changed.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="twisted"></category><category term="serialization"></category></entry><entry><title>Making use of twisted coiterate</title><link href="/blog/posts/2014/May/12/making-use-of-twisted-coiterate/" rel="alternate"></link><updated>2014-05-12T00:00:00+03:00</updated><author><name>AmvTek developers</name></author><id>tag:,2014-05-12:blog/posts/2014/May/12/making-use-of-twisted-coiterate/</id><summary type="html">&lt;p&gt;Twisted provides various ways to integrate &lt;strong&gt;&lt;span class="caps"&gt;CPU&lt;/span&gt; bound&lt;/strong&gt; operations or
&lt;strong&gt;blocking libraries&lt;/strong&gt; to the reactor. It provides very clean integration path
for &lt;a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/threading.html"&gt;threading&lt;/a&gt; or &lt;a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/process.html"&gt;external processes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, we describe an &lt;em&gt;under documented&lt;/em&gt; alternative, where the long
running task is implemented using an iterator that will be consumed
&lt;strong&gt;directly&lt;/strong&gt; in the reactor event loop after passing it to &lt;a class="reference external" href="http://twistedmatrix.com/documents/current/api/twisted.internet.task.html#coiterate"&gt;coiterate&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Where usable, coiteration allows to completely avoid using threading, bypassing
the well known python &lt;span class="caps"&gt;GIL&lt;/span&gt;&amp;nbsp;bottleneck&amp;#8230;&lt;/p&gt;
&lt;div class="section" id="basic-idea"&gt;
&lt;h2&gt;Basic&amp;nbsp;idea&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Coiteration&lt;/strong&gt; requires developers to use  a &lt;strong&gt;divide and conquer&lt;/strong&gt; strategy to
plan their task execution. In python, we will code the task using a generator
function or alternatively a class implementing the iterator&amp;nbsp;protocol.&lt;/p&gt;
&lt;p&gt;The task will be executed &lt;em&gt;step by step&lt;/em&gt; in the reactor event loop after passing
the iterator that represents it to &lt;strong&gt;coiterate&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="summing-integers"&gt;
&lt;h2&gt;Summing&amp;nbsp;integers&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s consider a python function which sums the N first integers, N being
arbitrary&amp;nbsp;large.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For &lt;em&gt;very&lt;/em&gt; large value of N, calling such function from the same thread as the one
inside which the &lt;strong&gt;reactor&lt;/strong&gt; is running, is not a good idea as the event loop
will be blocked for as long as this function needs to&amp;nbsp;return&amp;#8230;&lt;/p&gt;
&lt;div class="section" id="summing-using-coiteration"&gt;
&lt;h3&gt;Summing using&amp;nbsp;coiteration&lt;/h3&gt;
&lt;div class="section" id="a-first-approach"&gt;
&lt;h4&gt;A first&amp;nbsp;approach&lt;/h4&gt;
&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;reactor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet.task&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;coiterate&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Adding &lt;/span&gt;&lt;span class="si"&gt;%i&lt;/span&gt;&lt;span class="s2"&gt; to result&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="c1"&gt;# event loop can looks after other things...&lt;/span&gt;

    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;result is &lt;/span&gt;&lt;span class="si"&gt;%i&lt;/span&gt;&lt;span class="s2"&gt; &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;all_sum_steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;coiterate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_sum_steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;See gist &lt;a class="reference external" href="https://gist.github.com/amvtek/0aa479fbfb6f83621b40#file-coiterate_01-py"&gt;coiterate01.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;line 4&lt;/strong&gt; a generator function is defined, that return an iterator that will
calculate the sum of all integers until a certain value N. At &lt;strong&gt;line 17&lt;/strong&gt;, this
iterator is passed to &lt;strong&gt;coiterate&lt;/strong&gt; which will result in such iterator being
consumed in the reactor event loop in an optimal&amp;nbsp;way.&lt;/p&gt;
&lt;p&gt;Note that this does not make your iterator magically non blocking, as everywhere
else in Twisted, developer shall ensure that each iteration is non&amp;nbsp;blocking.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="obtaining-the-result"&gt;
&lt;h4&gt;Obtaining the&amp;nbsp;result&lt;/h4&gt;
&lt;p&gt;If you took the time to run the above &lt;em&gt;sum_all_integer &amp;#8230;&lt;/em&gt;, you have probably
been delighted to see the result being printed in the&amp;nbsp;console.&lt;/p&gt;
&lt;p&gt;Retrieving such result to make use of it, requires some additional efforts that
will be detailled&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s first observe that &lt;strong&gt;coiterate&lt;/strong&gt; is a well behaved Twisted citizen. As it
is starting an operation &lt;em&gt;(consumption of the argument iterator&amp;#8230;)&lt;/em&gt; that will
take some time to complete, it returns a &lt;strong&gt;Deferred&lt;/strong&gt;.  As you may expect, this
Deferred will fire when iteration is&amp;nbsp;over.&lt;/p&gt;
&lt;p&gt;If we attach a &lt;strong&gt;callback&lt;/strong&gt; function to this Deferred we will not receive our
result, but the same iterator that coiterate has consumed. Let&amp;#8217;s see a possible
solution to obtain a result from the&amp;nbsp;iterator.&lt;/p&gt;
&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;reactor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet.task&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;coiterate&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Adding &lt;/span&gt;&lt;span class="si"&gt;%i&lt;/span&gt;&lt;span class="s2"&gt; to result&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="c1"&gt;# event loop can looks after other things...&lt;/span&gt;

    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;result&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;return Deferred firing calculated sum...&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_result_cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ignored&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;return context[&amp;#39;result&amp;#39;]&amp;quot;&lt;/span&gt;

        &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;result&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Got result = &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt;

    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;all_sum_steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;deferred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coiterate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_sum_steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;deferred&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract_result_cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deferred&lt;/span&gt;

&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;See gist &lt;a class="reference external" href="https://gist.github.com/amvtek/0aa479fbfb6f83621b40#file-coiterate_02-py"&gt;coiterate_02.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s summarize how this code proceeds&amp;nbsp;:&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;line 4&lt;/strong&gt;, we define a &lt;strong&gt;generator function&lt;/strong&gt; which returns an iterator that
let us execute our task &lt;em&gt;step by step&lt;/em&gt;. As we also need a result from such
iterator, we pass it an additional &lt;strong&gt;context object&lt;/strong&gt; which provides a way to
&amp;#8220;return&amp;#8221; any result obtained during&amp;nbsp;iteration.&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;line 14&lt;/strong&gt;, we construct a well behaved python function that returns a
Deferred that will fire with the result we are awaiting. Internally this
function takes care of all the gory details of constructing the iterator that
will be passed to coiterate and extracting the result we&amp;nbsp;need.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="waiting-for-deferred"&gt;
&lt;h4&gt;Waiting for&amp;nbsp;Deferred&amp;#8230;&lt;/h4&gt;
&lt;p&gt;Meanwhile executing a &lt;em&gt;long running task&lt;/em&gt;, it is quite common to have to wait
some time until some externals operations complete. Twisted let our &lt;em&gt;coiterable&lt;/em&gt;
tasks indicate that they shall be paused until a certain &lt;strong&gt;Deferred&lt;/strong&gt; fires. To
achieve so, the only thing to do is to &lt;strong&gt;yield&lt;/strong&gt; the Deferred of interest out of
the task&amp;nbsp;iterator.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s see how we could have our &lt;em&gt;sum_all_integer&amp;#8230;&lt;/em&gt; wait &lt;strong&gt;1 second&lt;/strong&gt; in
between each iteration&amp;nbsp;step.&lt;/p&gt;
&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;reactor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet.task&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;coiterate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deferLater&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wait_some_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;return Deferred firing after t seconds&amp;quot;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deferLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;I was paused &lt;/span&gt;&lt;span class="si"&gt;%.02f&lt;/span&gt;&lt;span class="s2"&gt; seconds&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_pause_cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;callback printing result message...&amp;quot;&lt;/span&gt;

        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Adding &lt;/span&gt;&lt;span class="si"&gt;%i&lt;/span&gt;&lt;span class="s2"&gt; to result&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;

        &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wait_some_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print_pause_cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;    &lt;span class="c1"&gt;# we will be paused until d fires...&lt;/span&gt;

    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;result&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;See gist &lt;a class="reference external" href="https://gist.github.com/amvtek/0aa479fbfb6f83621b40#file-coiterate_03-py"&gt;coiterate_03.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;line 4&lt;/strong&gt; is the modified &lt;strong&gt;generator function&lt;/strong&gt; that will pause some time
in between each step. The wait_some_time function at &lt;strong&gt;line 6&lt;/strong&gt; could be
anything that returns a&amp;nbsp;Deferred.&lt;/p&gt;
&lt;p&gt;It is our experience that the &lt;strong&gt;yield to wait&lt;/strong&gt; approach which coiterate allows
greatly simplify coding &lt;em&gt;complex tasks&lt;/em&gt; with&amp;nbsp;Twisted.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="cancelling-coiteration"&gt;
&lt;h4&gt;Cancelling&amp;nbsp;coiteration&lt;/h4&gt;
&lt;p&gt;When requiring clients to wait long time to get the result of a long running
operation, we shall expect situations where the client will give up. In such
situations, we normally want to cleanup as soon as possible any resources
allocated to service such&amp;nbsp;client.&lt;/p&gt;
&lt;p&gt;Before showing how this can be achieved in the context of this example, let&amp;#8217;s
mention that if you need to control your task from the outside to pause it or
stop it, you should consider using &lt;a class="reference external" href="http://twistedmatrix.com/documents/current/api/twisted.internet.task.html#cooperate"&gt;cooperate&lt;/a&gt; instead of coiterate. Like
coiterate, cooperate shall be called with an iterator which will be consumed in
the reactor &lt;strong&gt;event loop&lt;/strong&gt;. Unlike coiterate that returns a Deferred that fires
when iteration is completed, cooperate returns a Task object that can be used to
&lt;strong&gt;pause&lt;/strong&gt; or &lt;strong&gt;stop&lt;/strong&gt; the ongoing&amp;nbsp;task&amp;#8230;&lt;/p&gt;
&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;reactor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet.defer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Deferred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancelledError&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;twisted.internet.task&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;coiterate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deferLater&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wait_some_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;return Deferred firing after t seconds&amp;quot;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deferLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;I was paused &lt;/span&gt;&lt;span class="si"&gt;%.02f&lt;/span&gt;&lt;span class="s2"&gt; seconds&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_pause_cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;callback printing result message...&amp;quot;&lt;/span&gt;

        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;

    &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

            &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Adding &lt;/span&gt;&lt;span class="si"&gt;%i&lt;/span&gt;&lt;span class="s2"&gt; to result&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;

            &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wait_some_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print_pause_cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;    &lt;span class="c1"&gt;# we will be paused until d fires...&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;result&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;GeneratorExit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;---&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Early termination...&amp;quot;&lt;/span&gt;

        &lt;span class="c1"&gt;# cancel pending Defferred&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;called&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;return Deferred firing calculated sum...&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_result_cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ignored&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;return context[&amp;#39;result&amp;#39;]&amp;quot;&lt;/span&gt;

        &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;result&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;suppress_cancel_log_eb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;trap CancelledError&amp;quot;&lt;/span&gt;

        &lt;span class="c1"&gt;# this suppress UnhandledError warning...&lt;/span&gt;
        &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancelledError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;all_sum_steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_iterator_to_sum_all_integers_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;deferred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Deferred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;all_sum_steps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;coiterate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_sum_steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chainDeferred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deferred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;deferred&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract_result_cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;deferred&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addErrback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;suppress_cancel_log_eb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deferred&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;start summing integers and stop after 3 seconds...&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_result_cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;print result if any...&amp;quot;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Got result = &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;

    &lt;span class="c1"&gt;# start sum calculation using coiteration...&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sum_all_integers_being_nice_to_reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print_result_cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# schedule cancellation after 3.00 seconds&lt;/span&gt;
    &lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callLater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;reactor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;See gist &lt;a class="reference external" href="https://gist.github.com/amvtek/0aa479fbfb6f83621b40#file-coiterate_04-py"&gt;coiterate_04.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At &lt;strong&gt;line 4&lt;/strong&gt; our generator function was again modified. At &lt;strong&gt;line 32&lt;/strong&gt;, an inner
handler block for the &lt;strong&gt;GeneratorExit&lt;/strong&gt; exception was added. This block will be
reached in case &lt;strong&gt;close&lt;/strong&gt; is called on iterator objects returned by our
generator function. In this block, we are cleaning up any pending deferred that
the task may be waiting&amp;nbsp;for.&lt;/p&gt;
&lt;p&gt;One would expect that cancelling the Deferred returned by coiterate would
automatically &lt;strong&gt;close&lt;/strong&gt; the related iterator, but this is not the case. Let&amp;#8217;s modify
the &lt;em&gt;sum_all_integer&amp;#8230;&lt;/em&gt; function for this to happen. At &lt;strong&gt;line 60&lt;/strong&gt;, we
construct the Deferred that &lt;em&gt;sum_all_integer&amp;#8230;&lt;/em&gt; will return, providing it a
cancellation function. Such function simply &lt;strong&gt;close&lt;/strong&gt; the iterator returned by
the generator function. This &lt;em&gt;helper&lt;/em&gt; Deferred is &lt;strong&gt;chained&lt;/strong&gt; to the Deferred
that coiterate returns, so that when no cancellation occurs, we get our&amp;nbsp;result&amp;#8230;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="twisted"></category><category term="python"></category></entry></feed>