Еще один шаблон похож на радио- или телепередачи, он называется «публика-
ция — подписка», или pub-sub. В рамках этого шаблона публикатор рассылает
данные. В простой системе их получат все подписчики. Однако зачастую подпис-
чики могут указать, что они заинтересованы только в определенных типах данных
(такие типы часто называются темами), и публикатор будет отправлять только
такую информацию. Поэтому, в отличие от шаблона «разветвление на входе», за-
данный фрагмент данных может получить более чем один подписчик. Если на тему
не подписался никто, данные будут проигнорированы.
Модель публикации-подписки
Модель публикации-подписки не является очередью — это широковещательная
система. Один (или более) процесс публикует сообщения. Каждый процесс-под-
писчик указывает, сообщения какого типа он хочет получать. Копия каждого со-
общения отправляется каждому подписчику, указавшему этот тип. Поэтому
некоторое сообщение может быть обработано однажды, более чем однажды или
ни разу. Каждый публикатор просто выполняет рассылку и не знает, кто — если
таковые есть — его слушает.
Redis
Вы можете создать быструю систему pub-sub с использованием Redis. Публикатор
создает сообщения, имеющие тему и значение, а подписчики указывают, какие
темы они хотят получать.
Так выглядит публикатор redis_pub.py:
import redis
import random
conn = redis.Redis()
cats = ['siamese', 'persian', 'maine coon', 'norwegian forest']
hats = ['stovepipe', 'bowler', 'tam-o-shanter', 'fedora']
for msg in range(10):
cat = random.choice(cats)
hat = random.choice(hats)
print('Publish: %s wears a %s' % (cat, hat))
conn.publish(cat, hat)
Каждая тема представляет собой породу кота, а сопутствующее значение — вид
шляпы.
Так выглядит подписчик redis_sub.py:
import redis
conn = redis.Redis()
Сети
319
topics = ['maine coon', 'persian']
sub = conn.pubsub()
sub.subscribe(topics)
for msg in sub.listen():
if msg['type'] == 'message':
cat = msg['channel']
hat = msg['data']
print('Subscribe: %s wears a %s' % (cat, hat))
Подписчик показывает, что он хочет принимать сообщения о котах породы
'maine coon' и 'persian' и никаких других. Метод listen() возвращает словарь. Если
он имеет тип 'message', это значит, что он был отправлен публикатору и совпадает