生成器client.events()
阻塞了 unix 套接字recv
调用。如果您不能等到下一个事件并break
退出循环,那么您需要中断套接字。
不幸的是,我找不到通过 docker-py 执行此操作的干净方法。我发现的唯一方法需要使用/覆盖私有方法,这当然是脆弱的。如果您正在寻找一个强大的解决方案,我建议您直接进行 api 调用,然后您可以自由地在套接字上设置自己的超时时间或在非阻塞模式下使用它。
话虽如此,要直接回答这个问题,这里有一种修补Client
类的方法,以将 api 响应作为属性添加到由events()
.
from docker import Client
class CustomGenerator(object):
def __init__(self, stream, response, decode):
self.stream = stream
self.response = response
self.decode = decode
def __iter__(self):
for item in super(CustomClient, self.stream).\
_stream_helper(self.response, self.decode):
yield item
class CustomClient(Client):
def _stream_helper(self, response, decode=False):
return CustomGenerator(self, response, decode)
得到响应后,您可以关闭套接字,这将在生成器中引发异常。在这个例子中,我使用一个线程在 5 秒后停止监听。
from threading import Timer
import requests
import socket
client = CustomClient(base_url="unix://var/run/docker.sock")
events = client.events()
def listen_for_events():
print("listening")
try:
for event in events:
print(event)
except requests.packages.urllib3.exceptions.ProtocolError:
pass
print("done listening")
def stop_listening():
sock = client._get_raw_response_socket(events.response)
sock.shutdown(socket.SHUT_RDWR)
Timer(5, stop_listening).start()
listen_for_events()