我正在尝试使用Kubernetes提供的事件流
api使用requests
模块。我遇到了一个看起来像的东西
缓冲问题:requests
模块似乎滞后一个事件。
我的代码看起来像这样:
r = requests.get('http://localhost:8080/api/v1beta1/watch/services',
stream=True)
for line in r.iter_lines():
print 'LINE:', line
当Kubernetes发出事件通知时,此代码将仅显示 当一个新事件进入时发出的最后一个事件 对于需要响应服务的代码几乎完全没用 添加/删除事件。
我通过在子进程中生成curl
而不是使用来解决这个问题
requests
库:
p = subprocess.Popen(['curl', '-sfN',
'http://localhost:8080/api/watch/services'],
stdout=subprocess.PIPE,
bufsize=1)
for line in iter(p.stdout.readline, b''):
print 'LINE:', line
这有效,但代价是一些灵活性。有办法吗?
避免requests
库的缓冲问题?
答案 0 :(得分:6)
此行为是由于iter_lines
的错误实施
requests
库中的方法。
iter_lines
遍历chunk_size
块中的响应内容
使用iter_content
迭代器的数据。如果少于
可用于从远程读取的chunk_size
字节数据
服务器(通常是在读取最后一行时的情况)
输出),读操作将阻塞直到chunk_size
个字节
数据可用。
我编写了自己的iter_lines
例程,该例程运行正常:
import os
def iter_lines(fd, chunk_size=1024):
'''Iterates over the content of a file-like object line-by-line.'''
pending = None
while True:
chunk = os.read(fd.fileno(), chunk_size)
if not chunk:
break
if pending is not None:
chunk = pending + chunk
pending = None
lines = chunk.splitlines()
if lines and lines[-1]:
pending = lines.pop()
for line in lines:
yield line
if pending:
yield(pending)
这是有效的,因为os.read
将返回少于chunk_size
个字节
数据而不是等待填充缓冲区。