간단히 naver.com 홈페이지를 fetch해오는 로직이 있다고 하자.

그리고 post request를 날려 이로직이 끝난뒤에 response를 받고 싶다면?


잘못된 사용 예)

    def post(self):

        self.test("test")

        print "done"


    @gen.coroutine

    def test(self, msg):

        print msg

        httpClient = AsyncHTTPClient()

        res = yield httpClient.fetch("http://www.naver.com")

        print res

        print "done"

        raise gen.Return(res) 

이렇게 하면 result는 이렇다

test

done

[web:1728] 200 POST /test (::1) 2.23ms (connection 종료, response 보냄)

HTTPResponse(...)

self.test()함수를 기다리지 않고 바로 done하고 response를 날리고 나중에 res가 도착하자 print가 되었다.

여기서 문제는 post() 함수는 기다리는 로직이 없고, 또한 asynchronous 데코도 없기때문에 로직이 끝나자 auto finish를 한것이다.


그럼 제대로 기다리려면 어떻게 해야할까? 방법은 2가지다.

1. @gen.coroutine 이용

    @gen.coroutine

    def post(self):

        res = yield self.test("test")

        print "done"


    @gen.coroutine

    def test(self, msg):

        print msg

        httpClient = AsyncHTTPClient()

        res = yield httpClient.fetch("http://www.naver.com")

        print res

        raise gen.Return(res)

yield를 써서 post함수 역시 test함수를 기다린다. 결과적으로 fetch를 기다리는것과 같다.

결과는

test

HTTPResponse

done

[web:1728] 200 POST /test (::1) 2.23ms (connection 종료, response 보냄)

이 된다.


2. @web.asynchronous 이용

이 경우에는 로직이 약간 변경된다. 기본적으로 post에서는 커넥션을 끊지 않을 뿐 post함수는 끝나고 단지 커넥션은 self.finish()를 요청하는곳에서 종료된다는것을 명시하는 것이다.

    @web.asynchronous    

    def post(self):

        self.test("test")


    @gen.coroutine

    def test(self, msg):

        print msg

        httpClient = AsyncHTTPClient()

        res = yield httpClient.fetch("http://www.naver.com")

        print res

        print "done"

        self.finish()

결과는 1번과 같다. 

'python > tornado' 카테고리의 다른 글

@web.asynchronous @gen.coroutine VS @gen.corutine  (0) 2014.04.10
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,