From 9017975276b72a05bf70865a7197d577c547e521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 13 Sep 2020 18:26:52 +0300 Subject: [PATCH] Update README.md --- throttling/README.md | 19 +++- throttling/etc/throttling-pattern.png | Bin 50223 -> 0 bytes throttling/etc/throttling-pattern.ucls | 88 ------------------ throttling/etc/throttling_urm.png | Bin 0 -> 53754 bytes .../com/iluwatar/throttling/CallsCount.java | 1 - 5 files changed, 14 insertions(+), 94 deletions(-) delete mode 100644 throttling/etc/throttling-pattern.png delete mode 100644 throttling/etc/throttling-pattern.ucls create mode 100644 throttling/etc/throttling_urm.png diff --git a/throttling/README.md b/throttling/README.md index 257bce54a..4a77638e1 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -10,12 +10,15 @@ tags: --- ## Intent + Ensure that a given client is not able to access service resources more than the assigned limit. ## Explanation + Real world example -> A large multinational corporation offers API to its customers. The API is rate-limited and each customer can only make certain amount of calls per second. +> A large multinational corporation offers API to its customers. The API is rate-limited and each +> customer can only make certain amount of calls per second. In plain words @@ -23,7 +26,9 @@ In plain words [Microsoft documentation](https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling) says -> Control the consumption of resources used by an instance of an application, an individual tenant, or an entire service. This can allow the system to continue to function and meet service level agreements, even when an increase in demand places an extreme load on resources. +> Control the consumption of resources used by an instance of an application, an individual tenant, +> or an entire service. This can allow the system to continue to function and meet service level +> agreements, even when an increase in demand places an extreme load on resources. **Programmatic Example** @@ -77,7 +82,8 @@ public final class CallsCount { } ``` -Next we introduce the service that the tenants are calling. To track the call count we use the throttler timer. +Next we introduce the service that the tenants are calling. To track the call count we use the +throttler timer. ```java public interface Throttler { @@ -134,7 +140,8 @@ class B2BService { } ``` -Now we are ready to see the full example in action. Tenant Adidas is rate-limited to 5 calls per second and Nike to 6. +Now we are ready to see the full example in action. Tenant Adidas is rate-limited to 5 calls per +second and Nike to 6. ```java public static void main(String[] args) { @@ -171,9 +178,11 @@ Now we are ready to see the full example in action. Tenant Adidas is rate-limite ## Class diagram -![alt text](./etc/throttling-pattern.png "Throttling pattern class diagram") + +![alt text](./etc/throttling_urm.png "Throttling pattern class diagram") ## Applicability + The Throttling pattern should be used: * When a service access needs to be restricted to not have high impacts on the performance of the service. diff --git a/throttling/etc/throttling-pattern.png b/throttling/etc/throttling-pattern.png deleted file mode 100644 index 59e590aaf6ddf262b0f036cc55655cd4d4e5819b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50223 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