[파이썬] eBest Xing api 실시간조회, 멀티스레드 설계 (1)
[파이썬] eBest Xing api 실시간조회, 멀티스레드 설계 (1)
[파이썬] eBest Xing api 실시간조회, 스레드 설계 구현 (2)
[파이썬] eBest Xing api 실시간조회, ThreadJob 구현 (3)
[파이썬] eBest Xing api 실시간조회, ConnectionManager 구현 (4)
[파이썬] eBest Xing api 실시간조회, QueryThreadJob 구현 (5)
[파이썬] eBest Xing api 실시간조회, NWS 뉴스 요청 구현 (6)
[파이썬] eBest Xing api 실시간조회, S3_ 코스피체결 구현 (7)
[파이썬] eBest Xing api 실시간조회, 테스트 및 실행 화면 (8)
증권사에서 주식 관련 정보를 조회할 수 있도록 API를 제공해주고 있다.
이베스트투자증권에서 제공해 주는 API를 통해 실시간 정보를 조회할 수 있는 프로그램을 멀티스레드로 설계, 구현해 보려고 한다.
멀티스레드로 설계하는 이유는 효율성 때문이다. 요청하는 쿼리가 하나이면 별다른 문제가 없지만 2개 이상일 경우 한 스레드에서 처리하기엔 병목현상이 발생할 것이다. 리퀘스트 A 때문에 리퀘스트 B가 기다려야 하는 현상이 발생할 수 있어서 설계부터 멀티스레드를 고려하였다.
설계에 앞서 이베스트에서 제공하는 API에 대해 알아볼 필요가 있다. 이베스트에서 제공하는 개발자용 프로그램인 ‘DevCenter’를 이용하면 사용하게 될 API의 명세도 확인할 수 있고 그 프로그램을 통해 쿼리를 테스트해 볼 수 있는 환경을 제공해준다. 아주 기똥찬 프로그램이다. Xing API는 이벤트 방식으로 응답을 준다. 비동기 방식이다. API의 성향(?)에 따라 내가 구현할 프로그램의 설계가 달라진다. 비동기 이벤트 방식은 응답이 언제 올지 예측할 수 없다. 멀티스레드를 적극적으로 이용하려는 이유 중 하나이다.
이제 만들 프로그램을 설계해 보겠다.
우선 스레드 기준으로 각각의 역할을 정의하였다.
MainThread는 말 그대로 구현할 프로그램의 메인이며, 연결을 관리하는 ConnectionManager, 실시간 뉴스 정보를 관리하는 RT_NWS, 실시간 코스피 종목 가격을 관리할 수 있는 RT_S3_KOSPI, 4가지로 정의하였다.
- MainThread 프로그램의 라이프사이클을 관리하는 스레드이다. 프로그램의 초기화, 셧다운 등을 관리한다. |
- ConnectionManager 이베스트투자증권으로 쿼리를 날리기 전에 로그인은 필수 작업이다. 이 스레드를 통해 이베스트투자증권으로 부터 인증을 받고 커넥션과 관련된 일을 담당한다. |
- RT_NWS NWS 쿼리는 이베스트투장증권에서 실시간으로 뉴스 제목 패킷을 보내준다. 이에 이벤트 리스너가 대기하고 있다가 보내준 데이터를 화면콘솔로 뿌려준다. |
- RT_S3_KOSPI S3_ 쿼리는 이베스트투자증권에 코스피 종목 단축코드를 알려주면 해당 종목의 매수 및 매도 이벤트가 발생할 때 마다 응답을 보내준다. 종목코드를 여러개 입력 할 수 있다. |
여러가지 쿼리들이 있지만 이 글에선 두 가지 쿼리만 다룰 것이다.
위에 정의한 역할에 대해 시퀀스 다이어그램으로 표현해 보았다.
1. MainThread에서는 ConnectionManager, RT_NWS, RT_S3_KOSPI 객체를 생성하고 각각의 start() 메서드를 통해 해당 스레드들을 시작한다. 각각의 스레드들은 정의된 초기화 과정을 거친다. 이 초기화 과정에서 API객체를 생성할 때 정의된 이벤트 클래스를 등록해 준다.
2. 스레드들이 초기화 과정을 마치면 Queue에 명령어가 들어오기를 기다린다. 멀티스레드에서 Queue를 사용하는 이유는 스레드간 연결고리를 만들어 줄 수 있는 가장 보편적인 방법이 ‘생산자-소비자 패턴’이기 때문이다.
3. MainThread에서 쿼리 명령어를 Queue에 등록하면 대기하고 있던 각각의 해당 스레드가 명령어 수신시 해당 명령어를 처리한다.
4. 각각의 스레드들은 초기화 시 생성된 Xing API객체를 통해 이베스트투자증권 서버에 요청하며, 응답은 등록된 이벤트 리스너에 의해 수신받는다.
여기서 눈여겨 봐야 할 부분은 ‘스레드들의 초기화 과정’이라고 표현한 부분이다. 진짜 스레드를 초기화한다는 의미가 아니고 정의된 ConnectionManager, RT_NWS, RT_S3_KOSPI 스레드가 시작할 때, 동작 수행에 꼭 필요한 과정이 필요하다는 뜻이다. (큐 객체를 생성하고, Xing API 객체를 생성하고..)
Xing API는 COM버전을 제공, 사용하였다. 파이썬이 Xing API의 객체를 얻기 위해 ‘win32com’ 라이브러리의 DispatchWithEvents 함수를 이용한다. 이 객체를 얻어올 때 MainThread가 아닌 각각의 스레드에서 얻어와야지 올바른 동작이 가능하다. 이 과정을 스레드 초기화 과정이라고 표현하였다. 이 부분은 당연할 수도 있지만 상당히 중요한 부분이다.
이렇게 큰 그림을 그렸고, 다음으로 클래스를 설계하고 구현해보도록 하겠다.