@@ -39,7 +39,6 @@ In this example a young human and an old dwarf walk into a bar. They start order
39
39
` BarCustomer ` class presents the clients of the ` Bartender ` API. ` CallsCount ` tracks the number of calls per ` BarCustomer ` .
40
40
41
41
``` java
42
-
43
42
@Getter
44
43
public class BarCustomer {
45
44
@@ -55,7 +54,9 @@ public class BarCustomer {
55
54
callsCount. addTenant(name);
56
55
}
57
56
}
57
+ ```
58
58
59
+ ``` java
59
60
@Slf4j
60
61
public final class CallsCount {
61
62
private final Map<String , AtomicLong > tenantCallsCount = new ConcurrentHashMap<> ();
@@ -85,7 +86,9 @@ Next, the service that the tenants are calling is introduced. To track the call
85
86
public interface Throttler {
86
87
void start ();
87
88
}
89
+ ```
88
90
91
+ ``` java
89
92
public class ThrottleTimerImpl implements Throttler {
90
93
91
94
private final int throttlePeriod;
@@ -142,36 +145,42 @@ class Bartender {
142
145
Now it is possible to see the full example in action. ` BarCustomer ` young human is rate-limited to 2 calls per second and the old dwarf to 4.
143
146
144
147
``` java
145
- public static void main(String [] args) {
146
- var callsCount = new CallsCount ();
147
- var human = new BarCustomer (" young human" , 2 , callsCount);
148
- var dwarf = new BarCustomer (" dwarf soldier" , 4 , callsCount);
148
+ @Slf4j
149
+ public class App {
149
150
150
- var executorService = Executors . newFixedThreadPool(2 );
151
+ public static void main (String [] args ) {
152
+ var callsCount = new CallsCount ();
153
+ var human = new BarCustomer (" young human" , 2 , callsCount);
154
+ var dwarf = new BarCustomer (" dwarf soldier" , 4 , callsCount);
151
155
152
- executorService. execute(() - > makeServiceCalls(human, callsCount));
153
- executorService. execute(() - > makeServiceCalls(dwarf, callsCount));
156
+ var executorService = Executors . newFixedThreadPool(2 );
154
157
155
- executorService. shutdown();
156
- try {
157
- executorService. awaitTermination(10 , TimeUnit . SECONDS );
158
- } catch (InterruptedException e) {
159
- LOGGER . error(" Executor service terminated: {}" , e. getMessage());
160
- }
161
- }
158
+ executorService. execute(() - > makeServiceCalls(human, callsCount));
159
+ executorService. execute(() - > makeServiceCalls(dwarf, callsCount));
162
160
163
- private static void makeServiceCalls(BarCustomer barCustomer, CallsCount callsCount) {
164
- var timer = new ThrottleTimerImpl (1000 , callsCount);
165
- var service = new Bartender (timer, callsCount);
166
- // Sleep is introduced to keep the output in check and easy to view and analyze the results.
167
- IntStream . range(0 , 50 ). forEach(i - > {
168
- service. orderDrink(barCustomer);
161
+ executorService. shutdown();
169
162
try {
170
- Thread . sleep(100 );
163
+ if (! executorService. awaitTermination(10 , TimeUnit . SECONDS )) {
164
+ executorService. shutdownNow();
165
+ }
171
166
} catch (InterruptedException e) {
172
- LOGGER . error( " Thread interrupted: {} " , e . getMessage() );
167
+ executorService . shutdownNow( );
173
168
}
174
- });
169
+ }
170
+
171
+ private static void makeServiceCalls (BarCustomer barCustomer , CallsCount callsCount ) {
172
+ var timer = new ThrottleTimerImpl (1000 , callsCount);
173
+ var service = new Bartender (timer, callsCount);
174
+ // Sleep is introduced to keep the output in check and easy to view and analyze the results.
175
+ IntStream . range(0 , 50 ). forEach(i - > {
176
+ service. orderDrink(barCustomer);
177
+ try {
178
+ Thread . sleep(100 );
179
+ } catch (InterruptedException e) {
180
+ LOGGER . error(" Thread interrupted: {}" , e. getMessage());
181
+ }
182
+ });
183
+ }
175
184
}
176
185
```
177
186
@@ -202,10 +211,6 @@ An excerpt from the example's console output:
202
211
18:46:37.148 [pool-1-thread-2] ERROR com.iluwatar.throttling.Bartender - I'm sorry dwarf soldier, you've had enough for today!
203
212
```
204
213
205
- ## Class diagram
206
-
207
- ![ Throttling] ( ./etc/throttling_urm.png " Throttling pattern class diagram ")
208
-
209
214
## Applicability
210
215
211
216
* You need to protect resources from being overwhelmed by too many requests.
@@ -239,5 +244,5 @@ Trade-offs:
239
244
240
245
## Credits
241
246
242
- * [ Throttling pattern] ( https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling )
243
- * [ Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications (Microsoft patterns & practices) ] ( https://www.amazon.com/gp/product/B00ITGHBBS/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=B00ITGHBBS&linkId=12aacdd0cec04f372e7152689525631a )
247
+ * [ Throttling pattern (Microsoft) ] ( https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling )
248
+ * [ Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications] ( https://amzn.to/4dLvowg )
0 commit comments