Skip to content

Commit 2bdbbd3

Browse files
committed
Merge branch 'master' into web-server
2 parents 7395d00 + cfcfdd1 commit 2bdbbd3

27 files changed

Lines changed: 3789 additions & 555 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ tex/flow-shop-images
3030
tex/flow-shop.markdown
3131
tex/frontmatter-images
3232
tex/frontmatter.tex
33+
tex/functionalDB-images
34+
tex/functionalDB.markdown
3335
tex/intro.tex
3436
tex/modeller-images
3537
tex/modeller.markdown
@@ -43,6 +45,7 @@ tex/sampler-images
4345
tex/sampler.markdown
4446
tex/spreadsheet-images
4547
tex/spreadsheet.markdown
48+
tex/static-analysis.markdown
4649
tex/template-engine.markdown
4750
html/content
4851
html/cache

blockcode/README.md

Lines changed: 89 additions & 59 deletions
Large diffs are not rendered by default.

build.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ def main(chapters=[], epub=False, pdf=False, html=False, mobi=False, pandoc_epub
1414
run('rm {}'.format(f))
1515

1616
chapter_dirs = [
17+
'static-analysis',
18+
'functionalDB',
1719
'flow-shop',
1820
'template-engine',
1921
'pedometer',
@@ -60,6 +62,7 @@ def main(chapters=[], epub=False, pdf=False, html=False, mobi=False, pandoc_epub
6062
]
6163

6264
image_paths = [
65+
'./functionalDB/functionalDB-images',
6366
'./flow-shop/flow-shop-images',
6467
'./pedometer/pedometer-images',
6568
'./sampler/sampler-images',

cluster/cluster.markdown

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
title: Clustering by Consensus
22
author: Dustin J. Mitchell
33

4+
_Dustin is an open source software developer and release engineer at Mozilla.
5+
He has worked on projects as varied as a host configuration system in Puppet, a
6+
Flask-based web framework, unit tests for firewall configurations, and a
7+
continuous integration framework in Twisted Python. Find him as [\@djmitche](http://github.com/djmitche) on
8+
GitHub or at [[email protected]](mailto:[email protected])._
9+
10+
## Introduction
411

512
In this chapter, we'll explore implementation of a network protocol designed to support reliable distributed computation.
613
Network protocols can be difficult to implement correctly, so we'll look at some techniques for minimizing bugs and for catching and fixing the remaining few.

crawler/crawler.markdown

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
title: A Web Crawler With asyncio Coroutines
22
author: A. Jesse Jiryu Davis and Guido van Rossum
33

4+
_A. Jesse Jiryu Davis is a staff engineer at MongoDB in New York. He wrote Motor, the async MongoDB Python driver, and he is the lead developer of the MongoDB C Driver and a member of the PyMongo team. He contributes to asyncio and Tornado. He writes at [http://emptysqua.re](http://emptysqua.re)._
5+
6+
_Guido van Rossum is the creator of Python, one of the major programming languages on and off the web. The Python community refers to him as the BDFL (Benevolent Dictator For Life), a title straight from a Monty Python skit. Guido's home on the web is [http://www.python.org/~guido/](http://www.python.org/~guido/)._
7+
8+
## Introduction
9+
410
Classical computer science emphasizes efficient algorithms that complete computations as quickly as possible. But many networked programs spend their time not computing, but holding open many connections that are slow, or have infrequent events. These programs present a very different challenge: to wait for a huge number of network events efficiently. A contemporary approach to this problem is asynchronous I/O, or "async".
511

612
This chapter presents a simple web crawler. The crawler is an archetypal async application because it waits for many responses, but does little computation. The more pages it can fetch at once, the sooner it completes. If it devotes a thread to each in-flight request, then as the number of concurrent requests rises it will run out of memory or other thread-related resource before it runs out of sockets. It avoids the need for threads by using asynchronous I/O.
@@ -82,7 +88,7 @@ This method not only wastes electricity, but it cannot efficiently await events
8288
Python 3.4's `DefaultSelector` uses the best `select`-like function available on your system. To register for notifications about network I/O, we create a non-blocking socket and register it with the default selector:
8389

8490
```python
85-
from selectors import DefaultSelector
91+
from selectors import DefaultSelector, EVENT_WRITE
8692

8793
selector = DefaultSelector()
8894

@@ -189,7 +195,7 @@ Here is the implementation of `connected`:
189195
def connected(self, key, mask):
190196
print('connected!')
191197
selector.unregister(key.fd)
192-
request = 'GET {} HTTP/1.0\r\nHost: xkcd.com\r\n\r\n'.format(url)
198+
request = 'GET {} HTTP/1.0\r\nHost: xkcd.com\r\n\r\n'.format(self.url)
193199
self.sock.send(request.encode('ascii'))
194200

195201
# Register the next callback.
@@ -306,7 +312,7 @@ It is also scalable. Compared to the 50k of memory per thread and the operating
306312

307313
The concept of a coroutine, dating to the elder days of computer science, is simple: it is a subroutine that can be paused and resumed. Whereas threads are preemptively multitasked by the operating system, coroutines multitask cooperatively: they choose when to pause, and which coroutine to run next.
308314

309-
There are many implementations of coroutines; even in Python there are several. The coroutines in the standard "asyncio" library in Python 3.4 are built upon generators, a Future class, and the "yield from" statement. Starting in Python 3.5, coroutines will be a native feature of the language itself[^17]; however, understanding coroutines as they were first implemented in Python 3.4, using pre-existing language facilities, is the foundation to tackle Python 3.5's native coroutines.
315+
There are many implementations of coroutines; even in Python there are several. The coroutines in the standard "asyncio" library in Python 3.4 are built upon generators, a Future class, and the "yield from" statement. Starting in Python 3.5, coroutines are a native feature of the language itself[^17]; however, understanding coroutines as they were first implemented in Python 3.4, using pre-existing language facilities, is the foundation to tackle Python 3.5's native coroutines.
310316

311317
To explain Python 3.4's generator-based coroutines, we will engage in an exposition of generators and how they are used as coroutines in asyncio, and trust you will enjoy reading it as much as we enjoyed writing it. Once we have explained generator-based coroutines, we shall use them in our async web crawler.
312318

@@ -789,10 +795,11 @@ except ImportError:
789795
We collect the workers' shared state in a crawler class, and write the main logic in its `crawl` method. We start `crawl` on a coroutine and run asyncio's event loop until `crawl` finishes:
790796

791797
```python
798+
loop = asyncio.get_event_loop()
799+
792800
crawler = crawling.Crawler('http://xkcd.com',
793801
max_redirect=10)
794802

795-
loop = asyncio.get_event_loop()
796803
loop.run_until_complete(crawler.crawl())
797804
```
798805

@@ -808,7 +815,7 @@ class Crawler:
808815

809816
# aiohttp's ClientSession does connection pooling and
810817
# HTTP keep-alives for us.
811-
self.session = aiohttp.ClientSession(loop=self.loop)
818+
self.session = aiohttp.ClientSession(loop=loop)
812819

813820
# Put (URL, max_redirect) in the queue.
814821
self.q.put((root_url, self.max_redirect))
@@ -1082,7 +1089,7 @@ If we squint so that the `yield from` statements blur, a coroutine looks like a
10821089

10831090
But when we open our eyes and focus on the `yield from` statements, we see they mark points when the coroutine cedes control and allows others to run. Unlike threads, coroutines display where our code can be interrupted and where it cannot. In his illuminating essay "Unyielding"[^4], Glyph Lefkowitz writes, "Threads make local reasoning difficult, and local reasoning is perhaps the most important thing in software development." Explicitly yielding, however, makes it possible to "understand the behavior (and thereby, the correctness) of a routine by examining the routine itself rather than examining the entire system."
10841091

1085-
This chapter was written during a renaissance in the history of Python and async. Generator-based coroutines, whose devising you have just learned, were released in the "asyncio" module with Python 3.4 in March 2014. In September 2015, Python 3.5 will be released with coroutines built in to the language itself. These native coroutines will be declared with the new syntax "async def", and instead of "yield from", they will use the new "await" keyword to delegate to a coroutine or wait for a Future.
1092+
This chapter was written during a renaissance in the history of Python and async. Generator-based coroutines, whose devising you have just learned, were released in the "asyncio" module with Python 3.4 in March 2014. In September 2015, Python 3.5 was released with coroutines built in to the language itself. These native coroutinesare declared with the new syntax "async def", and instead of "yield from", they use the new "await" keyword to delegate to a coroutine or wait for a Future.
10861093

10871094
Despite these advances, the core ideas remain. Python's new native coroutines will be syntactically distinct from generators but work very similarly; indeed, they will share an implementation within the Python interpreter. Task, Future, and the event loop will continue to play their roles in asyncio.
10881095

@@ -1125,4 +1132,4 @@ Now that you know how asyncio coroutines work, you can largely forget the detail
11251132
[^16]: Guido introduced the standard asyncio library, called "Tulip" then, at PyCon 2013.
11261133
</latex>
11271134

1128-
[^17]: Python 3.5's built-in coroutines are described in [PEP 492](https://www.python.org/dev/peps/pep-0492/), "Coroutines with async and await syntax." At the time of this writing, Python 3.5 was in beta, due for release in September 2015.
1135+
[^17]: Python 3.5's built-in coroutines are described in [PEP 492](https://www.python.org/dev/peps/pep-0492/), "Coroutines with async and await syntax."

functionalDB/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# FDB
22

3-
FDB (TODO - find a better name) is an in-memory, no-sql functional database, written in Clojure.
3+
CircleDB is an in-memory, no-sql functional database, written in Clojure.
44

55
It is a modest attempt to provide part of the functionality that the Datomic database provides (the main omitted functionality is the durability part).
66

0 commit comments

Comments
 (0)