2017-09-13 10 views
3

:비동기 aiohttp 코드의 문제점은 무엇입니까? 다음 코드를 사용하여 aiohttp를 들어

그것은 작동
async def send(self, msg, url): 
    async with aiohttp.ClientSession() as session: 
     async with session.post(url, data=msg) as response: 
      self._msg = response.read() 

async def recv(self): 
    return await self._msg 

... 대부분의 시간,하지만 가끔 (자주, 실제로는) 다양한 예외의 결과 - 일반적으로 잘린 응답, 또는 연결이 이미 닫힌 예외 인. 반면

는 다음 완벽하게 작동합니다 :

async def send(self, msg, url): 
    async with aiohttp.ClientSession() as session: 
     async with session.post(url, data=msg) as response: 
      self._msg = await response.read() 

async def recv(self): 
    return self._msg 

내가 두 번째 버전은 내 목적을 위해 기술적으로 부정확 내가 그것을 해결하기 위해 필요로하는 이유를 알고 싶습니다. (응답이 읽히기 전에 recv 함수가 호출 될 수 있기 때문에 올바르지 않습니다.)

+0

"응답을 읽기 전에 recv 함수가 호출 될 수 있기 때문에 올바르지 않습니다."- ca 인 경우 응답이 읽히기 전에 끈질 기게 기다린다. 그러면 첫 번째 버전에서 무엇이 '기다리고 있을까?' 'self._msg' 아직 설정되지 않았습니다. – user2357112

+0

정확히, 보내기가 끝나기 전까지는 recv를 호출하지 않습니다. 그러나 아, 그건 좋은 지적입니다. 두 버전 모두 근본적으로 잘못되었습니다. 개념적으로 '보내기'와 'recv'를 계속 유지하면서 수정 제안을 할 수 있습니까? – Arafangion

+0

(명확히하기 위해 : 고침을 고맙게 생각하지만,이 두 코드 샘플의 차이점을 이해하려면 실제 대답을 원합니다.) – Arafangion

답변

2

with은 컨텍스트 관리자로, 일반적으로 부기 내에있는 모든 구문 앞뒤에 일부 코드를 실행합니다. 의미, 첫 번째 recv 함수는 이미 닫힌 연결 또는이 줄을 따라 무언가를 참조하는 미래를 기다리고있을 가능성이 큽니다.

with open(...) as file: 
    file.read() 

이 그것을 대략 무엇이다 :

의는 다음과 같습니다 일부 코드가 있다고 가정 해 봅시다

file = open(...) 
file.read() 
file.close() 

그리고 이것은 당신이 무슨 일을하는지에 해당하는 당신의 첫 번째 예 :

file = open() 
file.close() 
... 
file.read() 
+0

그러면 미래가 무효화됩니다. – Arafangion

+1

"미래를 무효화"한다는 것이 무슨 뜻인지는 모르겠지만 기본적으로이 모든 일은 asyncio 문제가 아닙니다. 그것은 닫힌 소켓이나'response.read()'에서 깊은 곳에서 일어나는 다른 것을 읽는 문제입니다. –

+1

답변을 업데이트했습니다. –