pypubsub과 메시지 구조
[python
pypubsub
]
pypubsub이라는 라이브러리도 국내에서는 소개가 안된 것 같아 여기에 적어 놓는다.
먼저 pypubsub을 쓰기 전에 메시지의 생산자 및 구독자 구조를 알아야 한다.
구조의 개념은 간단하다.
여기에서 생산자는 메시지를 생성하여 구독자에게 전달한다. 구독자는 각각 토픽을 가지고 있는데 일종의 문패로 생각하면 쉽다. 생산자는 메시지를 생성할 때 어디에 메시지를 전달할지 토픽을 같이 얹어서 메시지 중계자에게 전달하면 중계자는 토픽을 검토하여 맞는 토픽을 가지고 있는 구독자에게 보낸다. 구독자 함수가 토픽으로 호출되는 것이다. 이 메시지 중계자 역할을 pypubsub이 한다.
from pubsub import pub
# 구독자 함수 생성.
def listener_alice(args):
print('Alice receives news about', args['headline'])
print(args['news'])
print(args['date'])
print()
def listener_bob(args):
print('Bob receives news about', args['headline'])
print(args['news'])
print(args['date'])
print()
# 구독자 등록
pub.subscribe(listener_alice, 'football')
pub.subscribe(listener_alice, 'chess')
pub.subscribe(listener_bob, 'football')
# 메시지 보내기
pub.sendMessage('football', args={'headline': 'Ronaldo',
'news': 'sold for $1M',
'date': '11/19/2021'})
pub.sendMessage('chess', args={'headline': 'AI',
'news': 'AlphaZero beats grandmaster Calse',
'date': '11/19/2021'})
17~19행은 구독자 함수에 명패를 달아 주는 작업이다. listener_alice에게는 ‘football’과 ‘chess’라는 두 개의 명패를 달아 주었고 listener_bob에도 ‘football’ 하나만 달아주었다.
22행은 명패가 ‘football’인 구독자 모두에게 args에 해당하는 데이터를 보낸다. 25행은 마찬가지로 명패가 ‘chess’인 구독자 모두에게 데이터를 보낸다.
수행 결과는 다음과 같다.
$ python3 2test.py
Alice receives news about Ronaldo
sold for $1M
11/19/2021
Bob receives news about Ronaldo
sold for $1M
11/19/2021
Alice receives news about AI
AlphaZero beats grandmaster Calse
11/19/2021
첫 번째 SendMessage는 명패가 football에게로 전달되어 구독자 함수가 수행되었으며, 두 번째 SendMessage도 명패가 chess인 구독자 함수에 메시지를 전달하였다.
이 라이브러리의 용도는 정말 많지만, 중요한 의미는 메시지 발생자와 구독자를 분리하는데 있다. 나중에 구독자 함수의 추가가 필요할 때, 발행자의 수정이 필요없이 그 메시지를 받기위한 명패(토픽)만 구독자 함수에 할당하여 추가하면 되기 때문이다. 코드의 유지보수성이 증가된다. 그리고 잘만 활용하면 코드의 호출 구조를 상당히 간단하게 바꿀 수 있지 않을까?
유의할 점은 이 함수는 싱글 쓰레드 하에서만 동작한다는 점이다. 다른 프로세스나 다른 애플리케이션에서의 전달은 안된다. 이런 경우에는 Kafka나 RabbitMQ 같은 메시지 큐 시스템을 도입해야 한다.