# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2009-2012, Marcel Hellkamp
# This file is distributed under the same license as the Bottle package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: Bottle 0.12-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-09 18:23\n"
"PO-Revision-Date: 2012-11-09 15:37+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

# 444d3f0f105f47b887bb0ba9822e1a1c
#: ../../async.rst:2
msgid "Primer to Asynchronous Applications"
msgstr "异步应用入门"

# 8d2cd170d03742b38a49e16d0f8b767f
#: ../../async.rst:4
msgid ""
"Asynchronous design patterns don't mix well with the synchronous nature of "
"`WSGI <http://www.python.org/dev/peps/pep-3333/>`_. This is why most "
"asynchronous frameworks (tornado, twisted, ...) implement a specialized API "
"to expose their asynchronous features. Bottle is a WSGI framework and shares "
"the synchronous nature of WSGI, but thanks to the awesome `gevent project "
"<http://www.gevent.org/>`_, it is still possible to write asynchronous "
"applications with bottle. This article documents the usage of Bottle with "
"Asynchronous WSGI."
msgstr ""
"异步设计模式和 `WSGI <http://www.python.org/dev/peps/pep-3333/>`_ 的同步本质"
"并不能很好地兼容。这就是为什么大部分的异步框架(tornado, twisted, ...)都实现了"
"专有的API来暴露它们的异步特征。Bottle是一个WSGI框架，也继承了WSGI的同步本质，"
"但是谢谢优秀的 `gevent项目 <http://www.gevent.org/>`_ ，我们可以使用Bottle来"
"编写异步应用。这份文档介绍了在Bottle中如何使用异步WSGI。"

# 9ba83091544148ce9ac672d1a4d08308
#: ../../async.rst:7
msgid "The Limits of Synchronous WSGI"
msgstr "同步WSGI的限制"

# d44c90a8c3454394a657b911f1ec85fc
#: ../../async.rst:9
msgid ""
"Briefly worded, the `WSGI specification (pep 3333) <http://www.python.org/"
"dev/peps/pep-3333/>`_ defines a request/response circle as follows: The "
"application callable is invoked once for each request and must return a body "
"iterator. The server then iterates over the body and writes each chunk to "
"the socket. As soon as the body iterator is exhausted, the client connection "
"is closed."
msgstr ""
"简单来说， `WSGI标准 (pep 3333) <http://www.python.org/dev/peps/pep-3333/>`_ "
"定义了下面这一个request/response的循环：每次请求到达的时候，应用中的callable"
"会被调用一次，返回一个主体iterator。接着服务器会遍历该主体，分块写入socket。"
"遍历完整个主体，就关闭客户端的连接。"

# 2ad0d26fdfa044e595ce3b9ea29d94be
#: ../../async.rst:11
msgid ""
"Simple enough, but there is a snag: All this happens synchronously. If your "
"application needs to wait for data (IO, sockets, databases, ...), it must "
"either yield empty strings (busy wait) or block the current thread. Both "
"solutions occupy the handling thread and prevent it from answering new "
"requests. There is consequently only one ongoing request per thread."
msgstr ""
"足够简单，但是存在一个小问题：所有这些都是同步的。如果你的应用需要等待数据"
"(IO, socket, 数据库, ...)，除了返回一个空字符串(忙等)，就只能阻塞当前线程。两"
"种办法都会占用当前线程，导致线程不能处理新的请求，只能处理当前的一个请求。"

# efb55442c2a049e4a4b41f47636975d5
#: ../../async.rst:13
msgid ""
"Most servers limit the number of threads to avoid their relatively high "
"overhead. Pools of 20 or less threads are common. As soon as all threads are "
"occupied, any new connection is stalled. The server is effectively dead for "
"everyone else. If you want to implement a chat that uses long-polling ajax "
"requests to get real-time updates, you'd reach the limited at 20 concurrent "
"connections. That's a pretty small chat."
msgstr ""
"大部分服务器都限制了线程的数量，避免伴随它们而来的资源消耗。常见的是一个线程"
"池，内有20个或更少数量的线程。一旦所有的线程都被占用了，任何新的请求都会阻"
"塞。事实上，对于其他人来说，服务器已经宕机了。如果你想实现一个聊天程序，使用"
"ajax轮询来获取实时消息，很快你就会受到线程数量的限制。这样能同时服务的用户就"
"太少了。"

# 84d8e03c7dcf45699f0880f591ce42a1
#: ../../async.rst:16
msgid "Greenlets to the rescue"
msgstr "救星，Greenlet"

# a608984f3b0648d2acb892828a6c0f1a
#: ../../async.rst:18
msgid ""
"Most servers limit the size of their worker pools to a relatively low number "
"of concurrent threads, due to the high overhead involved in switching "
"between and creating new threads. While threads are cheap compared to "
"processes (forks), they are still expensive to create for each new "
"connection."
msgstr ""
"大多数服务器的线程池都限制了线程池中线程的数量，避免创建和切换线程的代价。尽"
"管和创建进程(fork)的代价比起来，线程还是挺便宜的。但是也没便宜到可以接受为每"
"一个请求创建一个线程。"

# 715dab2ec22040969dc0826db174d77d
#: ../../async.rst:20
msgid ""
"The `gevent <http://www.gevent.org/>`_ module adds *greenlets* to the mix. "
"Greenlets behave similar to traditional threads, but are very cheap to "
"create. A gevent-based server can spawn thousands of greenlets (one for each "
"connection) with almost no overhead. Blocking individual greenlets has no "
"impact on the servers ability to accept new requests. The number of "
"concurrent connections is virtually unlimited."
msgstr ""
"`gevent <http://www.gevent.org/>`_ 模块添加了 *greenlet* 的支持。greenlet和传"
"统的线程类似，但其创建只需消耗很少的资源。基于gevent的服务器可以生成成千上万"
"的greenlet，为每个连接分配一个greenlet也毫无压力。阻塞greenlet，也不会影响到"
"服务器接受新的请求。同时处理的连接数理论上是没有限制的。"

# 1c816479188a4c71995d01d1ca2d70d3
#: ../../async.rst:22
msgid ""
"This makes creating asynchronous applications incredibly easy, because they "
"look and feel like synchronous applications. A gevent-based server is "
"actually not asynchronous, but massively multi-threaded. Here is an example::"
msgstr ""
"这令创建异步应用难以置信的简单，因为它们看起来很想同步程序。基于gevent服务器"
"实际上不是异步的，是大规模多线程。下面是一个例子。"

# 71732a6c95b64c75af73cd0e090c3d25
#: ../../async.rst:39
msgid ""
"The first line is important. It causes gevent to monkey-patch most of "
"Python's blocking APIs to not block the current thread, but pass the CPU to "
"the next greenlet instead. It actually replaces Python's threading with "
"gevent-based pseudo-threads. This is why you can still use ``time.sleep()`` "
"which would normally block the whole thread. If you don't feel comfortable "
"with monkey-patching python built-ins, you can use the corresponding gevent "
"functions (``gevent.sleep()`` in this case)."
msgstr ""
"第一行很重要。它让gevent monkey-patch了大部分Python的阻塞API，让它们不阻塞当"
"前线程，将CPU让给下一个greenlet。它实际上用基于gevent的伪线程替换了Python的线"
"程。这就是你依然可以使用 ``time.sleep()`` 这个照常来说会阻塞线程的函数。如果"
"这种monkey-patch的方式感令你感到不舒服，你依然可以使用gevent中相应的函数 "
"``gevent.sleep()`` 。"

# 926721db7acd4a2485edfa8d60ad76e7
#: ../../async.rst:41
msgid ""
"If you run this script and point your browser to ``http://localhost:8080/"
"stream``, you should see `START`, `MIDDLE`, and `END` show up one by one "
"(rather than waiting 8 seconds to see them all at once). It works exactly as "
"with normal threads, but now your server can handle thousands of concurrent "
"requests without any problems."
msgstr ""
"如果你运行了上面的代码，接着访问 ``http://localhost:8080/stream`` ，你可看到 "
"`START`, `MIDDLE`, 和 `END` 这几个字样依次出现(用时大约8秒)。它像普通的线程一"
"样工作，但是现在你的服务器能同时处理成千上万的连接了。"

# b4f28934ee8344eb9e56ac7e4eb25c95
#: ../../async.rst:45
msgid ""
"Some browsers buffer a certain amount of data before they start rendering a "
"page. You might need to yield more than a few bytes to see an effect in "
"these browsers. Additionally, many browsers have a limit of one concurrent "
"connection per URL. If this is the case, you can use a second browser or a "
"benchmark tool (e.g. `ab` or `httperf`) to measure performance."
msgstr ""
"一些浏览器在开始渲染一个页面之前，会缓存确定容量的数据。在这些浏览器上，你需"
"要返回更多的数据才能看到效果。另外，很多浏览器限制一个URL只使用一个连接。在这"
"种情况下，你可以使用另外的浏览器，或性能测试工具(例如： `ab` 或 `httperf` )来"
"测试性能。"

# d05ad991545847cbb4200f76a4e8ec53
#: ../../async.rst:52
msgid "Event Callbacks"
msgstr "事件回调函数"

# 555abf8c45d04c9f8bf27aa654774f9b
#: ../../async.rst:54
msgid ""
"A very common design pattern in asynchronous frameworks (including tornado, "
"twisted, node.js and friends) is to use non-blocking APIs and bind callbacks "
"to asynchronous events. The socket object is kept open until it is closed "
"explicitly to allow callbacks to write to the socket at a later point. Here "
"is an example based on the `tornado library <http://www.tornadoweb.org/"
"documentation#non-blocking-asynchronous-requests>`_::"
msgstr ""
"异步框架的常见设计模式(包括 tornado, twisted, node.js 和 friends)，是使用非阻"
"塞的API，绑定回调函数到异步事件上面。在显式地关闭之前，socket会保持打开，以便"
"稍后回调函数往socket里面写东西。下面是一个基于 `tornado <http://www."
"tornadoweb.org/documentation#non-blocking-asynchronous-requests>`_ 的例子。"

# ff3f82109f784c47b1707ac9e3a5f831
#: ../../async.rst:63
msgid ""
"The main benefit is that the request handler terminates early. The handling "
"thread can move on and accept new requests while the callbacks continue to "
"write to sockets of previous requests. This is how these frameworks manage "
"to process a lot of concurrent requests with only a small number of OS "
"threads."
msgstr ""
"主要的好处就是MainHandler能早早结束，在回调函数继续写socket来响应之前的请求的"
"时候，当前线程能继续接受新的请求。这样就是为什么这类框架能同时处理很多请求，"
"只使用很少的操作系统线程。"

# 5e39762fd5df49a39faab304e9a290b1
#: ../../async.rst:65
msgid ""
"With Gevent+WSGI, things are different: First, terminating early has no "
"benefit because we have an unlimited pool of (pseudo)threads to accept new "
"connections. Second, we cannot terminate early because that would close the "
"socket (as required by WSGI). Third, we must return an iterable to conform "
"to WSGI."
msgstr ""
"对于Gevent和WSGI来说，情况就不一样了：首先，早早结束没有好处，因为我们的(伪)"
"线程池已经没有限制了。第二，我们不能早早结束，因为这样会关闭socket(WSGI要求如"
"此)。第三，我们必须返回一个iterator，以遵守WSGI的约定。"

# 0d083ebaebd841c1b677840fbb7e1829
#: ../../async.rst:67
msgid ""
"In order to conform to the WSGI standard, all we have to do is to return a "
"body iterable that we can write to asynchronously. With the help of `gevent."
"queue <http://www.gevent.org/gevent.queue.html>`_, we can *simulate* a "
"detached socket and rewrite the previous example as follows::"
msgstr ""
"为了遵循WSGI规范，我们只需返回一个iterable的实体，异步地将其写回客户端。在 "
"`gevent.queue <http://www.gevent.org/gevent.queue.html>`_ 的帮助下，我们可以 "
"*模拟* 一个脱管的socket，上面的例子可写成这样。"

# c2dc80f344ff438dae10bf531b546f54
#: ../../async.rst:77
msgid ""
"From the server perspective, the queue object is iterable. It blocks if "
"empty and stops as soon as it reaches ``StopIteration``. This conforms to "
"WSGI. On the application side, the queue object behaves like a non-blocking "
"socket. You can write to it at any time, pass it around and even start a new "
"(pseudo)thread that writes to it asynchronously. This is how long-polling is "
"implemented most of the time."
msgstr ""
"从服务器的角度来看，queue对象是iterable的。如果为空，则阻塞，一旦遇到 "
"``StopIteration`` 则停止。这符合WSGI规范。从应用的角度来看，queue对象表现的像"
"一个不会阻塞socket。你可以在任何时刻写入数据，pass it around，甚至启动一个新"
"的(伪)线程，异步写入。这是在大部分情况下，实现长轮询。"

# 8fbf44264bb54dca80871e505abd6fa2
#: ../../async.rst:81
msgid "Finally: WebSockets"
msgstr "最后： WebSockets"

# 07ae2daba04a4d888fbee239cbfdbbee
#: ../../async.rst:83
msgid ""
"Lets forget about the low-level details for a while and speak about "
"WebSockets. Since you are reading this article, you probably know what "
"WebSockets are: A bidirectional communication channel between a browser "
"(client) and a web application (server)."
msgstr ""
"让我们暂时忘记底层的细节，来谈谈WebSocket。既然你正在阅读这篇文章，你有可能已"
"经知道什么是WebSocket了，一个在浏览器(客户端)和Web应用(服务端)的双向的交流通"
"道。"

# 66508ae9eb304f00960be55668071c01
#: ../../async.rst:85
msgid ""
"Thankfully the `gevent-websocket <http://pypi.python.org/pypi/gevent-"
"websocket/>`_ package does all the hard work for us. Here is a simple "
"WebSocket endpoint that receives messages and just sends them back to the "
"client::"
msgstr ""
"感谢 `gevent-websocket <http://pypi.python.org/pypi/gevent-websocket/>`_ 包帮"
"我们做的工作。下面是一个WebSocket的简单例子，接受消息然后将其发回客户端。"

# 0e40e6a944d144f7bffce3b8696fbcae
#: ../../async.rst:109
msgid ""
"The while-loop runs until the client closes the connection. You get the "
"idea :)"
msgstr "while循环直到客户端关闭连接的时候才会终止。You get the idea :)"

# 79623942975c406d9beb3f23fa1191ea
#: ../../async.rst:111
msgid "The client-site JavaScript API is really straight forward, too::"
msgstr "客户端的JavaScript API也十分简洁明了::"

# 14e90902f8e64556adcf90b146d2bd97
#, fuzzy
#~ msgid "new added linnnnnnne"
#~ msgstr "新加的一行"
