-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathpub_sub_example.py
More file actions
98 lines (72 loc) · 2.82 KB
/
Copy pathpub_sub_example.py
File metadata and controls
98 lines (72 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
Publish/Subscribe pattern demonstration.
Implements a simple in-process pub/sub message broker to illustrate
the decoupled communication pattern used in systems like Kafka, Redis
Pub/Sub, and cloud messaging services.
No external dependencies required.
Usage:
python pub_sub_example.py
"""
import threading
import time
from collections import defaultdict
class MessageBroker:
"""A simple thread-safe in-process pub/sub message broker."""
def __init__(self):
self._subscribers = defaultdict(list)
self._lock = threading.Lock()
def subscribe(self, topic: str, callback):
"""Register a callback for a given topic."""
with self._lock:
self._subscribers[topic].append(callback)
def unsubscribe(self, topic: str, callback):
"""Remove a callback from a topic."""
with self._lock:
self._subscribers[topic].remove(callback)
def publish(self, topic: str, message):
"""Deliver a message to all subscribers of a topic."""
with self._lock:
handlers = list(self._subscribers[topic])
for handler in handlers:
handler(topic, message)
# ---------- Subscriber helpers ----------
def make_logger(name: str):
"""Return a subscriber callback that prints received messages."""
def handler(topic, message):
print(f" [{name}] received on '{topic}': {message}")
return handler
# ---------- Main ----------
def main():
broker = MessageBroker()
print("=" * 55)
print("Pub/Sub Pattern Demo")
print("=" * 55)
print()
# Create named subscribers
order_logger = make_logger("OrderService")
inventory_logger = make_logger("InventoryService")
analytics_logger = make_logger("AnalyticsService")
# Subscribe to topics
broker.subscribe("order.created", order_logger)
broker.subscribe("order.created", inventory_logger)
broker.subscribe("order.created", analytics_logger)
broker.subscribe("order.shipped", order_logger)
broker.subscribe("order.shipped", analytics_logger)
# Publish messages
print("Publishing 'order.created' ...")
broker.publish("order.created", {"order_id": 101, "item": "Laptop", "qty": 1})
print()
print("Publishing 'order.shipped' ...")
broker.publish("order.shipped", {"order_id": 101, "carrier": "FedEx"})
print()
# Unsubscribe demonstration
print("Unsubscribing AnalyticsService from 'order.created' ...")
broker.unsubscribe("order.created", analytics_logger)
print()
print("Publishing 'order.created' again ...")
broker.publish("order.created", {"order_id": 102, "item": "Keyboard", "qty": 2})
print()
print("Key takeaway: Pub/Sub decouples publishers from subscribers,")
print("allowing independent scaling and flexible message routing.")
if __name__ == "__main__":
main()