2014-12-06 3 views
1

일을하는 어리석은 방법 일지 모르지만 여기에 설명되어 있습니다. 보내고받는 HTTP 요청을 응답 처리에서 분리하려고합니다.파이프에 Network.Socket.ByteString.recv가 발생합니다. (알 수없는 오류)

import Pipes 
import qualified Pipes.HTTP as HTTP 
import Pipes.Core 
import qualified Pipes.ByteString as PB 
import Network.Socket (withSocketsDo) 

fetch m url = do 
    req <- lift $ HTTP.parseUrl url 
    resp <- lift $ HTTP.withHTTP req m return 
    url' <- respond $ HTTP.responseBody resp 
    fetch m url' 

client :: Client String (Producer PB.ByteString IO()) IO() 
client = do 
      b <- request "http://www.google.com" 
      lift $ runEffect $ b >-> PB.stdout 

main = withSocketsDo $ HTTP.withManager HTTP.tlsManagerSettings $ \m -> 
    runEffect $ fetch m +>> client 

합법적으로 보입니다. 그러나 나는 응답의 일부를 인쇄하고 "Network.Socket.ByteString.recv : failed (Unknown error)"오류가 발생합니다. 다르게해야 할 일은 무엇입니까?

HTTP.withHTTP req m return 

이 기능을 사용하면 그것에서 탈출 할당하는 리소스를 할 수 없습니다 단어 with로 시작 때 대회 (유형에 의해 강제되지 않음)이 있습니다 :

+1

관련 분류 : http://stackoverflow.com/questions/9406463/withfile-vs-openfile – user3237465

답변

3

오류는이 부분입니다 그것이 둘러싸는 블록. 이유는 이러한 withXXX 함수가 블록 완료시 리소스를 삭제하므로 해당 지점 이후의 리소스가 유효하지 않기 때문입니다.

그런데 어떤 일이 발생했는지 withHTTP 블록에서 응답을 시도했지만 응답 코드는 이미 삭제되었습니다. 해결책은 Pipes.Safe.bracket을 사용하여 파이프 내에서 안전하게 자원을 확보 할 수있는 pipes-safe을 사용하는 것입니다.

fetch m url = do 
    req <- lift $ HTTP.parseUrl url 
    url' <- bracket openSomething closeSomething $ \resp -> do 
     respond $ HTTP.responseBody resp 
    fetch m url' 

resprespond 완료 때까지 해제되지 않도록 할 것이다 : 당신이해야 할 모든은 개폐 동작을 제공한다.

+0

감사합니다. 무엇을 열거 나 닫을 지 알 수있는 표준 방법이 있습니까? (이 경우'withHTTP'는'withResponse' 내부에 있고,'withResponse'는 그것을 설명했다.) –

+0

보통'with' 함수와 같은 모듈에서 제공 될 것입니다. 또한'resource' 타입을 제공하는'resourcet' 패키지를 확인하십시오. 이 타입을 사용하면'open'과'close' 액션을 묶어서 나중에 다시 복구 할 수 있습니다. –