Skip to content

Commit 9b71479

Browse files
committed
Update README.md
1 parent 3c4ae6c commit 9b71479

File tree

1 file changed

+31
-73
lines changed

1 file changed

+31
-73
lines changed

poison-pill/README.md

Lines changed: 31 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,31 @@ tags:
1010
---
1111

1212
## Intent
13-
Poison Pill is known predefined data item that allows to provide graceful shutdown for separate distributed consumption
14-
process.
13+
14+
Poison Pill is known predefined data item that allows to provide graceful shutdown for separate
15+
distributed consumption process.
1516

1617
## Explanation
1718

1819
Real world example
1920

20-
> Let's think about a message queue with one producer and one consumer. The producer keeps pushing new messages in the queue and the consumer keeps reading them. Finally when it's time to gracefully shut down the producer sends the poison pill message.
21+
> Let's think about a message queue with one producer and one consumer. The producer keeps pushing
22+
> new messages in the queue and the consumer keeps reading them. Finally when it's time to
23+
> gracefully shut down the producer sends the poison pill message.
2124
2225
In plain words
2326

2427
> Poison Pill is a known message structure that ends the message exchange.
2528
2629
**Programmatic Example**
2730

28-
Let's define the message structure first.
31+
Let's define the message structure first. There's interface `Message` and implementation
32+
`SimpleMessage`.
2933

3034
```java
3135
public interface Message {
3236

33-
Message POISON_PILL = new Message() {
34-
35-
@Override
36-
public void addHeader(Headers header, String value) {
37-
throw poison();
38-
}
39-
40-
@Override
41-
public String getHeader(Headers header) {
42-
throw poison();
43-
}
44-
45-
@Override
46-
public Map<Headers, String> getHeaders() {
47-
throw poison();
48-
}
49-
50-
@Override
51-
public void setBody(String body) {
52-
throw poison();
53-
}
54-
55-
@Override
56-
public String getBody() {
57-
throw poison();
58-
}
59-
60-
private RuntimeException poison() {
61-
return new UnsupportedOperationException("Poison");
62-
}
63-
64-
};
37+
...
6538

6639
enum Headers {
6740
DATE, SENDER
@@ -110,7 +83,9 @@ public class SimpleMessage implements Message {
11083
}
11184
```
11285

113-
Next we define the types related to the message queue.
86+
To pass messages we are using message queues. Here we define the types related to the message queue:
87+
`MqPublishPoint`, `MqSubscribePoint` and `MessageQueue`. `SimpleMessageQueue` implements all these
88+
interfaces.
11489

11590
```java
11691
public interface MqPublishPoint {
@@ -146,29 +121,15 @@ public class SimpleMessageQueue implements MessageQueue {
146121
}
147122
```
148123

149-
Now we need to create the message producer and consumer.
124+
Next we need message `Producer` and `Consumer`. Internally they use the message queues from above.
125+
It's important to notice that when `Producer` stops, it sends out the poison pill to inform
126+
`Consumer` that the messaging has finished.
150127

151128
```java
152129
public class Producer {
130+
131+
...
153132

154-
private static final Logger LOGGER = LoggerFactory.getLogger(Producer.class);
155-
156-
private final MqPublishPoint queue;
157-
private final String name;
158-
private boolean isStopped;
159-
160-
/**
161-
* Constructor.
162-
*/
163-
public Producer(String name, MqPublishPoint queue) {
164-
this.name = name;
165-
this.queue = queue;
166-
this.isStopped = false;
167-
}
168-
169-
/**
170-
* Send message to queue.
171-
*/
172133
public void send(String body) {
173134
if (isStopped) {
174135
throw new IllegalStateException(String.format(
@@ -187,9 +148,6 @@ public class Producer {
187148
}
188149
}
189150

190-
/**
191-
* Stop system by sending poison pill.
192-
*/
193151
public void stop() {
194152
isStopped = true;
195153
try {
@@ -203,19 +161,8 @@ public class Producer {
203161

204162
public class Consumer {
205163

206-
private static final Logger LOGGER = LoggerFactory.getLogger(Consumer.class);
207-
208-
private final MqSubscribePoint queue;
209-
private final String name;
210-
211-
public Consumer(String name, MqSubscribePoint queue) {
212-
this.name = name;
213-
this.queue = queue;
214-
}
164+
...
215165

216-
/**
217-
* Consume message.
218-
*/
219166
public void consume() {
220167
while (true) {
221168
try {
@@ -255,13 +202,24 @@ Finally we are ready to present the whole example in action.
255202
}).start();
256203
```
257204

205+
Program output:
206+
207+
```
208+
Message [hand shake] from [PRODUCER_1] received by [CONSUMER_1]
209+
Message [some very important information] from [PRODUCER_1] received by [CONSUMER_1]
210+
Message [bye!] from [PRODUCER_1] received by [CONSUMER_1]
211+
Consumer CONSUMER_1 receive request to terminate.
212+
```
213+
258214
## Class diagram
215+
259216
![alt text](./etc/poison-pill.png "Poison Pill")
260217

261218
## Applicability
262-
Use the Poison Pill idiom when
263219

264-
* Need to send signal from one thread/process to another to terminate
220+
Use the Poison Pill idiom when:
221+
222+
* There's a need to send signal from one thread/process to another to terminate.
265223

266224
## Real world examples
267225

0 commit comments

Comments
 (0)