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()