본문 바로가기

About/Flask

[Python] Flask Signal (Blinker)

시그널

플라스크는 시그널(signal) 라이브러리인 Blinker 를 통합한다.

이 라이브러리는 특정 이벤트를 '구독' 했다가 이벤트가 발생했을 때 필요한 함수를 실행한다.

여기서 말하는 이벤트는 고유한 이름표를 갖고 blinker.signal 클래스를 통해 생성된 인스턴스이다.

플라스크 0.12는 요청을 처리하는 과정 중 중요한 순간마다 총 10개의 시그널을 발생시킨다. (시그널은 다음 사이트 참고)

  • 시그널은 connect 함수를 사용해서 특정 이벤트를 등록할 수 있다.
  • 시그널은 코드가 시그널의 send 함수를 호출하면 트리거된다.
  • send 함수는 추가적인 인수를 받아서 모든 등록된 함수에 데이터를 전달한다.

다음 예제에서는 request_finished 시그널에 finished 함수를 등록한다.

우선 blinker를 설치하자

pip3 install blinker

예제 코드

# flask_blinker.py
from flask import Flask, jsonify, g, request_finished
from flask.signals import signals_available

if not signals_available:
    # blinker가 없는 경우
    raise RuntimeError("install blinker > pip install blinker")

app = Flask(__name__)

def finished(sender, response, **extra):
    print('about to send a Response')
    print(response)


request_finished.connect(finished) # request_finished 시그널에 finished 함수 등록


@app.route('/api')
def my_microservice():
    return jsonify({"Hello": "World"})


if __name__ == "__main__":
    app.run()
  • 요청이 끝난 경우 finished() ** 함수가 호출되어 서버에 **response 가 출력된다.
  • 위의 예제 처럼 request 객체가 만들어지고 처리되고 소멸되는 과정에서 발생하는 시그널들은 특히 로그를 남길 때 유용하다.

실행 결과

about to send a Response
<Response 18 bytes [200 OK]>
  • 서버에 요청이 오고 사라지는 경우 다음과 같이 출력된다.

  • 블링커 사용 시 한가지 유의해야할 점이 있는데 모든 등록된 함수들은 signal.send 호출 시 특별한 순서 없이 동기적으로 호출된다는 점이다. 따라서 너무 많은 시그널을 사용하면 요청 처리 시간도 그만큼 늘어나므로 병목현상 을 유발할 수 있다.
  • 응답에 영향을 미치지 않는 작업이 필요하다면 RabbitMQ 와 같은 비동기 큐를 사용해 작업을 큐에 넣고 다른 분리된 서비스에서 이 작업을 처리하는 방식을 고려할 수 있다.

다음 도서를 참고하였습니다.

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=191830482 

 

파이썬 마이크로서비스

파이썬에 대한 기본 지식, 커맨드라인, HTTP 기반 애플리케이션에 대한 기본 지식을 갖추고 있으며, 파이썬 3를 활용한 마이크로서비스 개발, 테스트, 확장, 관리 방법을 배우고 싶은 독자를 대상