2015-11-13 40 views
3

如何才能請求docker-py事件停止events流可迭代?例如,我想要停下來觀看碼頭事件。停止docker-py事件流迭代

from docker import Client 


client = Client(base_url='unix://var/run/docker.sock') 
events = client.events(decode=True) 

for event in events: 
    print(event) 

print('exited') 

client.events()返回發電機建立here

回答

2

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

爲了能夠中斷等待下一個事件時,可以通過聽串聯2秒時限的事件採用events()方法sinceuntil參數。

from datetime import datetime, timedelta 

import docker 
client = docker.from_env() 

delta = timedelta(seconds=2) 
since = datetime.utcnow() 
until = datetime.utcnow() + delta 
while True: 
    for event in client.events(since=since, until=until, decode=True): 
     print(event) 
    since = until 
    until = datetime.utcnow() + delta 

由於您等待事件持續2秒,您的執行線程將被阻止最多2秒。所以,如果用戶點擊Ctrl+C,腳本將很快終止。