问题:我需要向服务器发送许多HTTP请求.我只能使用一个连接(不可协商的服务器限制).服务器的响应时间加上网络延迟太高了 - 我落后了.
请求通常不会更改服务器状态,也不依赖于先前请求的响应.所以我的想法是简单地将它们发送到彼此之上,将响应对象排入队列,并依赖于Content-Length:传入响应以将传入的回复提供给下一个等待的响应对象.换句话说:将请求传递给服务器.
这当然不是完全安全的(任何没有Content-Length的回复:意味着麻烦),但我不在乎 - 在这种情况下,我总是可以重试任何排队的请求.(安全的方法是在发送下一位之前等待标题.这可能对我有所帮助.没办法预先测试.)
因此,理想情况下,我希望以下客户端代码(使用客户端延迟来模拟网络延迟)在三秒钟内运行.
现在有64000美元的问题:是否有一个已经完成此操作的Python库,或者我需要自己编写?我的代码使用gevent; 如果需要,我可以使用Twisted,但Twisted的标准连接池不支持流水线请求.如果有必要,我也可以为某个C库编写一个包装器,但我更喜欢本机代码.
#!/usr/bin/python
import gevent.pool
from gevent import sleep
from time import time
from geventhttpclient import HTTPClient
url = 'http://local_server/100k_of_lorem_ipsum.txt'
http = HTTPClient.from_url(url, concurrency=1)
def get_it(http):
print time(),"Queueing request"
response = http.get(url)
print time(),"Expect header data"
# Do something with the header, just to make sure that it has arrived
# (the greenlet should block until then)
assert response.status_code == 200
assert response["content-length"] > 0
for h in response.items():
pass
print time(),"Wait …Run Code Online (Sandbox Code Playgroud) 我有一个声明性映射:
class User(base):
username = Column(Unicode(30), unique=True)
Run Code Online (Sandbox Code Playgroud)
我怎么能告诉 sqlalchemy 这个属性不能被修改?我想出的解决方法有点笨拙:
from werkzeug.utils import cached_property
# regular @property works, too
class User(base):
_username = Column('username', Unicode(30), unique=True)
@cached_property
def username(self):
return self._username
def __init__(self, username, **kw):
super(User,self).__init__(**kw)
self._username=username
Run Code Online (Sandbox Code Playgroud)
在数据库列权限级别上执行此操作将不起作用,因为并非所有数据库都支持该操作。
给定此示例代码
#!/usr/bin/python3
import asyncio
async def f1():
await f2()
async def f2():
try:
await asyncio.sleep(1)
except BaseException as exc:
import pdb;pdb.set_trace()
pass
async def main():
f = asyncio.ensure_future(f1())
await asyncio.sleep(0.5)
f.cancel()
await f
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
断点处的堆栈跟踪如下所示:
(Pdb) w
/tmp/t.py(19)<module>()
-> loop.run_until_complete(main())
/usr/lib/python3.5/asyncio/base_events.py(325)run_until_complete()
-> self.run_forever()
/usr/lib/python3.5/asyncio/base_events.py(295)run_forever()
-> self._run_once()
/usr/lib/python3.5/asyncio/base_events.py(1254)_run_once()
-> handle._run()
/usr/lib/python3.5/asyncio/events.py(125)_run()
-> self._callback(*self._args)
/usr/lib/python3.5/asyncio/tasks.py(293)_wakeup()
-> self._step(exc)
/usr/lib/python3.5/asyncio/tasks.py(241)_step()
-> result = coro.throw(exc)
> /tmp/t.py(11)f2()
-> pass
Run Code Online (Sandbox Code Playgroud)
这很糟糕,因为我不再看到最初是从f1()调用f2()的。
鉴于Python能够通过简单的单步操作做到这一点,我如何检索原始调用堆栈?:
$ python3 t.py
> /tmp/t.py(11)f2()
-> pass
(Pdb) s
--Return--
> …Run Code Online (Sandbox Code Playgroud)