Skip to content

Commit

Permalink
docs: update throttling
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed May 27, 2024
1 parent 8372d92 commit a6458c4
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions throttling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ In this example a young human and an old dwarf walk into a bar. They start order
`BarCustomer` class presents the clients of the `Bartender` API. `CallsCount` tracks the number of calls per `BarCustomer`.

```java

@Getter
public class BarCustomer {

Expand All @@ -55,7 +54,9 @@ public class BarCustomer {
callsCount.addTenant(name);
}
}
```

```java
@Slf4j
public final class CallsCount {
private final Map<String, AtomicLong> tenantCallsCount = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -85,7 +86,9 @@ Next, the service that the tenants are calling is introduced. To track the call
public interface Throttler {
void start();
}
```

```java
public class ThrottleTimerImpl implements Throttler {

private final int throttlePeriod;
Expand Down Expand Up @@ -142,36 +145,42 @@ class Bartender {
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.

```java
public static void main(String[] args) {
var callsCount = new CallsCount();
var human = new BarCustomer("young human", 2, callsCount);
var dwarf = new BarCustomer("dwarf soldier", 4, callsCount);
@Slf4j
public class App {

var executorService = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
var callsCount = new CallsCount();
var human = new BarCustomer("young human", 2, callsCount);
var dwarf = new BarCustomer("dwarf soldier", 4, callsCount);

executorService.execute(() -> makeServiceCalls(human, callsCount));
executorService.execute(() -> makeServiceCalls(dwarf, callsCount));
var executorService = Executors.newFixedThreadPool(2);

executorService.shutdown();
try {
executorService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
LOGGER.error("Executor service terminated: {}", e.getMessage());
}
}
executorService.execute(() -> makeServiceCalls(human, callsCount));
executorService.execute(() -> makeServiceCalls(dwarf, callsCount));

private static void makeServiceCalls(BarCustomer barCustomer, CallsCount callsCount) {
var timer = new ThrottleTimerImpl(1000, callsCount);
var service = new Bartender(timer, callsCount);
// Sleep is introduced to keep the output in check and easy to view and analyze the results.
IntStream.range(0, 50).forEach(i -> {
service.orderDrink(barCustomer);
executorService.shutdown();
try {
Thread.sleep(100);
if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
LOGGER.error("Thread interrupted: {}", e.getMessage());
executorService.shutdownNow();
}
});
}

private static void makeServiceCalls(BarCustomer barCustomer, CallsCount callsCount) {
var timer = new ThrottleTimerImpl(1000, callsCount);
var service = new Bartender(timer, callsCount);
// Sleep is introduced to keep the output in check and easy to view and analyze the results.
IntStream.range(0, 50).forEach(i -> {
service.orderDrink(barCustomer);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
LOGGER.error("Thread interrupted: {}", e.getMessage());
}
});
}
}
```

Expand Down Expand Up @@ -202,10 +211,6 @@ An excerpt from the example's console output:
18:46:37.148 [pool-1-thread-2] ERROR com.iluwatar.throttling.Bartender - I'm sorry dwarf soldier, you've had enough for today!
```

## Class diagram

![Throttling](./etc/throttling_urm.png "Throttling pattern class diagram")

## Applicability

* You need to protect resources from being overwhelmed by too many requests.
Expand Down Expand Up @@ -239,5 +244,5 @@ Trade-offs:

## Credits

* [Throttling pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling)
* [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)
* [Throttling pattern (Microsoft)](https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling)
* [Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications](https://amzn.to/4dLvowg)

0 comments on commit a6458c4

Please sign in to comment.