You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this chapter, we'll explore implementation of a network protocol designed to support reliable distributed computation.
6
13
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.
Copy file name to clipboardExpand all lines: crawler/crawler.markdown
+14-7Lines changed: 14 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,12 @@
1
1
title: A Web Crawler With asyncio Coroutines
2
2
author: A. Jesse Jiryu Davis and Guido van Rossum
3
3
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
+
4
10
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".
5
11
6
12
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
82
88
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:
83
89
84
90
```python
85
-
from selectors import DefaultSelector
91
+
from selectors import DefaultSelector, EVENT_WRITE
86
92
87
93
selector = DefaultSelector()
88
94
@@ -189,7 +195,7 @@ Here is the implementation of `connected`:
@@ -306,7 +312,7 @@ It is also scalable. Compared to the 50k of memory per thread and the operating
306
312
307
313
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.
308
314
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.
310
316
311
317
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.
312
318
@@ -789,10 +795,11 @@ except ImportError:
789
795
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:
790
796
791
797
```python
798
+
loop = asyncio.get_event_loop()
799
+
792
800
crawler = crawling.Crawler('http://xkcd.com',
793
801
max_redirect=10)
794
802
795
-
loop = asyncio.get_event_loop()
796
803
loop.run_until_complete(crawler.crawl())
797
804
```
798
805
@@ -808,7 +815,7 @@ class Crawler:
808
815
809
816
# aiohttp's ClientSession does connection pooling and
@@ -1082,7 +1089,7 @@ If we squint so that the `yield from` statements blur, a coroutine looks like a
1082
1089
1083
1090
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."
1084
1091
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.
1086
1093
1087
1094
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.
1088
1095
@@ -1125,4 +1132,4 @@ Now that you know how asyncio coroutines work, you can largely forget the detail
1125
1132
[^16]: Guido introduced the standard asyncio library, called "Tulip" then, at PyCon 2013.
1126
1133
</latex>
1127
1134
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."
Copy file name to clipboardExpand all lines: functionalDB/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# FDB
2
2
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.
4
4
5
5
It is a modest attempt to provide part of the functionality that the Datomic database provides (the main omitted functionality is the durability part).
0 commit comments