Skip to content

Commit c797f2b

Browse files
HTML also.
1 parent bef87cf commit c797f2b

2 files changed

Lines changed: 14 additions & 20 deletions

File tree

crawler/crawler.markdown

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,21 +1074,15 @@ But when we open our eyes and focus on the `yield from` statements, we see they
10741074

10751075
Now that you know how asyncio coroutines work, you can largely forget the details. The machinery is tucked behind a dapper interface. But understanding the fundamentals empowers you to code correctly and efficiently in modern async environments.
10761076

1077-
[^1]: https://mail.python.org/pipermail/python-ideas/2012-September/016192.html
1077+
[^4]: [https://glyph.twistedmatrix.com/2014/02/unyielding.html](https://glyph.twistedmatrix.com/2014/02/unyielding.html)
10781078

1079-
[^2]: http://pyvideo.org/video/1667/keynote
1079+
[^5]: [https://docs.python.org/3/library/queue.html](https://docs.python.org/3/library/queue.html)
10801080

1081-
[^3]: https://groups.google.com/d/msg/python-tulip/bmphRrryuFk/aB45sEJUomYJ
1081+
[^6]: [https://docs.python.org/3/library/asyncio-sync.html](https://docs.python.org/3/library/asyncio-sync.html)
10821082

1083-
[^4]: https://glyph.twistedmatrix.com/2014/02/unyielding.html
1083+
[^7]: For a complex solution to this problem, see [http://www.tornadoweb.org/en/stable/stack_context.html](http://www.tornadoweb.org/en/stable/stack_context.html)
10841084

1085-
[^5]: https://docs.python.org/3/library/queue.html
1086-
1087-
[^6]: https://docs.python.org/3/library/asyncio-sync.html
1088-
1089-
[^7]: For a complex solution to this problem, see http://www.tornadoweb.org/en/stable/stack_context.html
1090-
1091-
[^8]: http://www.kegel.com/c10k.html
1085+
[^8]: [http://www.kegel.com/c10k.html](http://www.kegel.com/c10k.html)
10921086

10931087
[^9]: The actual `asyncio.Queue` implementation uses an `asyncio.Event` in place of the Future shown here. The difference is an Event can be reset, whereas a Future cannot transition from resolved back to pending.
10941088

tex/crawler.tex

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
run out of threads before we run out of sockets. Per-thread overhead or
8686
system limits on threads are the bottleneck.
8787

88-
In his influential article ``The C10K problem''\footnote{http://www.kegel.com/c10k.html},
88+
In his influential article ``The C10K problem''\footnote{\url{http://www.kegel.com/c10k.html}},
8989
Dan Kegel outlines the limitations of multithreading for I/O
9090
concurrency. He begins,
9191

@@ -496,7 +496,7 @@
496496
exception handler for a chain of callbacks, the way a ``try / except''
497497
block wraps a function call and its tree of descendents.\footnote{For a
498498
complex solution to this problem, see
499-
http://www.tornadoweb.org/en/stable/stack\_context.html}
499+
\url{http://www.tornadoweb.org/en/stable/stack_context.html}}
500500

501501
So, even apart from the long debate about the relative efficiencies of
502502
multithreading and async, there is this other debate regarding which is
@@ -1230,15 +1230,15 @@
12301230
once its work is done.
12311231
12321232
Imagine if the workers were threads. How would we express the crawler's
1233-
algorithm? We could use a synchronized queue\footnote{https://docs.python.org/3/library/queue.html}
1233+
algorithm? We could use a synchronized queue\footnote{\url{https://docs.python.org/3/library/queue.html}}
12341234
from the Python standard library. Each time an item is put in the queue,
12351235
the queue increments its count of ``tasks''. Worker threads call
12361236
\texttt{task\_done} after completing work on an item. The main thread
12371237
blocks on \texttt{Queue.join} until each item put in the queue is
12381238
matched by a \texttt{task\_done} call, then it exits.
12391239
12401240
Coroutines use the exact same pattern with a queue from asyncio! First
1241-
we import asyncio's queue\footnote{https://docs.python.org/3/library/asyncio-sync.html}:
1241+
we import asyncio's queue\footnote{\url{https://docs.python.org/3/library/asyncio-sync.html}}:
12421242
12431243
\begin{Shaded}
12441244
\begin{Highlighting}[]
@@ -1545,10 +1545,10 @@
15451545
event unpauses \texttt{join} and the main coroutine completes.
15461546
15471547
The queue code that coordinates the workers and the main coroutine is
1548-
like this\footnote{The actual asyncio.Queue implementation uses an
1549-
asyncio.Event in place of the Future shown here. The difference is an
1550-
Event can be reset, whereas a Future cannot transition from resolved
1551-
back to pending.}:
1548+
like this\footnote{The actual \texttt{asyncio.Queue} implementation uses
1549+
an \texttt{asyncio.Event} in place of the Future shown here. The
1550+
difference is an Event can be reset, whereas a Future cannot
1551+
transition from resolved back to pending.}:
15521552
15531553
\begin{Shaded}
15541554
\begin{Highlighting}[]
@@ -1696,7 +1696,7 @@
16961696
statements, we see they mark points when the coroutine cedes control and
16971697
allows others to run. Unlike threads, coroutines display where our code
16981698
can be interrupted and where it cannot. In his illuminating essay
1699-
``Unyielding''\footnote{https://glyph.twistedmatrix.com/2014/02/unyielding.html},
1699+
``Unyielding''\footnote{\url{https://glyph.twistedmatrix.com/2014/02/unyielding.html}},
17001700
Glyph Lefkowitz writes, ``Threads make local reasoning difficult, and
17011701
local reasoning is perhaps the most important thing in software
17021702
development.'' Explicitly yielding, however, makes it possible to

0 commit comments

Comments
 (0)