2015-01-25 3 views
7

requests 모듈을 사용하여 Kubernetes api에서 제공되는 이벤트 스트림을 사용하려고합니다. 나는 버퍼링 문제처럼 보였습니다 : requests 모듈은 하나의 이벤트에 의해 지연되는 것처럼 보입니다.Python "requests"라이브러리로 HTTP 응답 스트리밍 읽기

나는 이런 식으로 뭔가 보이는 코드를 가지고는 Kubernetes 이벤트 알림을 방출로

r = requests.get('http://localhost:8080/api/v1beta1/watch/services', 
       stream=True) 

for line in r.iter_lines(): 
    print 'LINE:', line 

,이 코드 만 표시됩니다 이 거의 쓸모가 만드는 새로운 이벤트가 들어올 때 방출되는 마지막 이벤트, 이벤트 추가/삭제에 응답해야하는 코드의 경우

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 

이 작동하지만, 유연성의 비용 :

나는 서브 프로세스에 curl을 산란 대신 requests 라이브러리를 사용하여이 문제를 해결했다. requests 라이브러리의 버퍼링 문제를 피할 수있는 방법이 있습니까?

답변

5

이 문제는 requests 라이브러리의 iter_lines 메서드가 버그로 인해 구현 되었기 때문에 발생합니다.

iter_linesiter_content 반복기를 사용하여 chunk_size 블록 블록의 응답 내용을 반복합니다. chunk_size 미만의 데이터가 서버 (일반적으로 출력의 마지막 행을 읽을 때 해당)에서 읽을 수있는 경우 바이트의 데이터를 사용할 수있을 때까지 읽기 작업이 차단됩니다. os.read 오히려 채우기 위해 버퍼를 기다리는 것보다보다 chunk_size 바이트의 데이터를 를 반환하기 때문에이 작동

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) 

:

나는 올바르게 작동 내 자신의 iter_lines 루틴을 작성했습니다.

+0

어떤 구현이 올바른지 논증 할 수 있습니다. 데이터가 더 많아지면 가짜 "논리적 줄 바꿈"을 삽입합니다. 올바른 접근법은 데이터의 전체 크기 (하나는 TCP 통신에 대한 요구 사항 임)를 찾아내는 것으로 알려진 끝에 부분 읽기만 사용하는 것입니다. –

+0

기존 구현이 정확하다고 주장 할 수 있다고 생각하지 않습니다. 내 테스트는 엄격한 테스트를 거치지 않았지만 확실히 개선되었습니다. 이상적인 업스트림 패치로 제출 된보다 정확한 구현은 매우 유용합니다. – larsks

+0

@ivan_pozdeev * "올바른 방법은 데이터의 전체 크기 (TCP 통신에 대한 요구 사항을 지정)를 찾는 것입니다."* - 아니요, TCP는 * 스트림 *이며 무한 길이를 가질 수 있습니다. 나는 당신이 그 말을 들었는지 모르지만 근본적으로 사실이 아닙니다. –

관련 문제