Repository: iluwatar/java-design-patterns
Issue: Circuit Breaker pattern
Labels: epic: pattern

http://martinfowler.com/bliki/CircuitBreaker.html

The basic idea behind the circuit breaker is very simple. You wrap a protected function call in a circuit breaker object, which monitors for failures. Once the failures reach a certain threshold, the circuit breaker trips, and all further calls to the circuit breaker return with an error, without the protected call being made at all. Usually you'll also want some kind of monitor alert if the circuit breaker trips.

A production ready implementation of pattern can be found here.
https://github.com/Comcast/jrugged/blob/master/jrugged-core/src/main/java/org/fishwife/jrugged/CircuitBreaker.java


Issue comments:
From the implementation, CircuitBreaker-State Pattern is a great pattern
compound to use for our implementation. The state pattern is to map
different state of the CircuitBreaker.  I love this pattern.

On Thu, Mar 31, 2016 at 6:30 AM, Narendra Pathai notifications@github.com
wrote:

> http://martinfowler.com/bliki/CircuitBreaker.html
> 
> The basic idea behind the circuit breaker is very simple. You wrap a
> protected function call in a circuit breaker object, which monitors for
> failures. Once the failures reach a certain threshold, the circuit breaker
> trips, and all further calls to the circuit breaker return with an error,
> without the protected call being made at all. Usually you'll also want some
> kind of monitor alert if the circuit breaker trips.
> 
> A production ready implementation of pattern can be found here.
> 
> https://github.com/Comcast/jrugged/blob/master/jrugged-core/src/main/java/org/fishwife/jrugged/CircuitBreaker.java
> 
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly or view it on GitHub
> https://github.com/iluwatar/java-design-patterns/issues/413

@geniusgeek Yes we used this pattern for years in production but didnt know its name. Found it today while exploring cloud patterns. We had implemented it without official name n now i am going to refactor our production code to use it.

http://techblog.netflix.com/2011/12/making-netflix-api-more-resilient.html

https://msdn.microsoft.com/en-us/library/dn589784.aspx

http://www.hascode.com/2017/02/resilient-architecture-circuit-breakers-for-java-hystrix-vert-x-javaslang-and-failsafe-examples/ (link contributed by @rinormaloku)
Hi .. can I work on this one ?
Ok @MohitNarula 
Issue is free
Hi, wondering if I could take this issue up since it's free? Would love to contribute to this awesome repository 😄 
Wonderful @PalAditya, please go ahead. Looking forward to your pull request.

Pull request review comments:
The plugins are already defined in parent pom.xml and not needed here
You can use local-variable type inference here (var)
Use final where member variables don't change
Use local-variable type inference (var)
Could it be constant? Looks a bit cryptic
The calculation here is hard to understand. We need at least comment there.
Also in tests var can be used extensively

Patch that resolved the issue:
diff --git a/circuit-breaker/README.md b/circuit-breaker/README.md
new file mode 100644
index 000000000000..db75ca58c0d0
--- /dev/null
+++ b/circuit-breaker/README.md
@@ -0,0 +1,188 @@
+---
+layout: pattern
+title: CircuitBreaker
+folder: circuit-breaker
+permalink: /patterns/circuit-breaker/
+categories: Other
+tags:
+ - Java
+ - Performance
+ - Difficulty-Intermediate
+---
+
+## Intent
+
+Handle costly remote *procedure/service* calls in such a way that the failure of a **single** service/component cannot bring the whole application down, and we can reconnect to the service as soon as possible.
+
+## Explanation
+
+Real world example
+
+> Imagine a Web App that has both local (example: files and images) and remote (example: database entries) to serve. The database might not be responding due to a variety of reasons, so if the application keeps trying to read from the database using multiple threads/processes, soon all of them will hang and our entire web application will crash. We should be able to detect this situation and show the user an appropriate message so that he/she can explore other parts of the app unaffected by the database failure without any problem. 
+
+In plain words
+
+> Allows us to save resources when we know a remote service failed. Useful when all parts of our application are highly decoupled from each other, and failure of one component doesn't mean the other parts will stop working.
+
+Wikipedia says
+
+> **Circuit breaker** is a design pattern used in modern software development. It is used to detect failures and encapsulates the logic of preventing a failure from constantly recurring, during maintenance, temporary external system failure or unexpected system difficulties.
+
+So, how does this all come together?
+
+## Programmatic Example
+With the above example in mind we will imitate the functionality in a simple manner. We have two services: A *monitoring service* which will mimic the web app and will make both **local** and **remote** calls.
+
+The service architecture is as follows:
+
+![alt text](./etc/ServiceDiagram.PNG "Service Diagram")
+
+In terms of code, the End user application is:
+
+```java
+public class App {
+   
+  private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+    
+  public static void main(String[] args) {
+    var obj = new MonitoringService();
+    var circuitBreaker = new CircuitBreaker(3000, 1, 2000 * 1000 * 1000); 
+    var serverStartTime = System.nanoTime();
+    while (true) {
+      LOGGER.info(obj.localResourceResponse());
+      LOGGER.info(obj.remoteResourceResponse(circuitBreaker, serverStartTime));
+      LOGGER.info(circuitBreaker.getState());
+      try {
+        Thread.sleep(5 * 1000); 
+      } catch (InterruptedException e) {
+        LOGGER.error(e.getMessage());
+      }
+    }
+  }
+}
+```
+
+The monitoring service is: 
+
+``` java
+public class MonitoringService {
+
+  public String localResourceResponse() {
+    return "Local Service is working";
+  }
+
+  public String remoteResourceResponse(CircuitBreaker circuitBreaker, long serverStartTime) {
+    try {
+      return circuitBreaker.call("delayedService", serverStartTime);
+    } catch (Exception e) {
+      return e.getMessage();
+    }
+  }
+}
+```
+As it can be seen, it does the call to get local resources directly, but it wraps the call to remote (costly) service in a circuit breaker object, which prevents faults as follows:
+
+```java
+public class CircuitBreaker {
+  private final long timeout;
+  private final long retryTimePeriod;
+  long lastFailureTime;
+  int failureCount;
+  private final int failureThreshold;
+  private State state;
+  private final long futureTime = 1000 * 1000 * 1000 * 1000;
+
+  CircuitBreaker(long timeout, int failureThreshold, long retryTimePeriod) {
+    this.state = State.CLOSED;
+    this.failureThreshold = failureThreshold;
+    this.timeout = timeout;
+    this.retryTimePeriod = retryTimePeriod;
+    this.lastFailureTime = System.nanoTime() + futureTime;
+    this.failureCount = 0;
+  }
+    
+  private void reset() {
+    this.failureCount = 0;
+    this.lastFailureTime = System.nanoTime() + futureTime; 
+    this.state = State.CLOSED;
+  }
+
+  private void recordFailure() {
+    failureCount = failureCount + 1;
+    this.lastFailureTime = System.nanoTime();
+  }
+    
+  protected void setState() {
+    if (failureCount > failureThreshold) { 
+      if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
+        state = State.HALF_OPEN;
+      } else {
+        state = State.OPEN;
+      }
+    } else {
+      state = State.CLOSED;
+    }
+  }
+    
+  public String getState() {
+    return state.name();
+  }
+  
+  public void setStateForBypass(State state) {
+    this.state = state;
+  }
+   
+  public String call(String serviceToCall, long serverStartTime) throws Exception {
+    setState();
+    if (state == State.OPEN) {
+      return "This is stale response from API";
+    } else {
+      if (serviceToCall.equals("delayedService")) {
+        var delayedService = new DelayedService(20);
+        var response = delayedService.response(serverStartTime);
+        if (response.split(" ")[3].equals("working")) {
+          reset();
+          return response;
+        } else {
+          recordFailure();
+          throw new Exception("Remote service not responding");
+        }
+      } else {
+        throw new Exception("Unknown Service Name");
+      }
+    }
+  }
+}
+```
+
+How does the above pattern prevent failures? Let's understand via this finite state machine implemented by it.
+
+![alt text](./etc/StateDiagram.PNG "State Diagram")
+
+- We initialize the Circuit Breaker object with certain parameters: **timeout**, **failureThreshold** and **retryTimePeriod** which help determine how resilient the API is.
+- Initially, we are in the **closed** state and the remote call to API happens.
+- Every time the call succeeds, we reset the state to as it was in the beginning.
+- If the number of failures cross a certain threshold, we move to the **open** state, which acts just like an open circuit and prevents remote service calls from being made, thus saving resources. (Here, we return the response called ```stale response from API```)
+- Once we exceed the retry timeout period, we move to the **half-open** state and make another call to the remote service again to check if the service is working so that we can serve fresh content. A *failure* sets it back to **open** state and another attempt is made after retry timeout period, while a *success* sets it to **closed** state so that everything starts working normally again. 
+
+
+## Applicability
+Use the Circuit Breaker pattern when
+
+- Building a fault-tolerant application where failure of some services shouldn't bring the entire application down.
+- Building an continuously incremental/continuous delivery application, as some of it's components can be upgraded without shutting it down entirely.
+
+## Related Patterns
+
+- [Retry Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/retry)
+
+## Real world examples
+* [Spring Circuit Breaker module](https://spring.io/guides/gs/circuit-breaker)
+* [Netflix Hystrix API](https://github.com/Netflix/Hystrix)
+
+## Credits
+
+* [Understanding Circuit Breaker Pattern](https://itnext.io/understand-circuitbreaker-design-pattern-with-simple-practical-example-92a752615b42)
+* [Martin Fowler on Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html)
+* [Fault tolerance in a high volume, distributed system](https://medium.com/netflix-techblog/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a)
+* [Microsoft docs](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)
diff --git a/circuit-breaker/pom.xml b/circuit-breaker/pom.xml
new file mode 100644
index 000000000000..b6587b061f7a
--- /dev/null
+++ b/circuit-breaker/pom.xml
@@ -0,0 +1,40 @@
+<!--
+
+    The MIT License
+    Copyright (c) 2014 Ilkka Seppälä
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iluwatar</groupId>
+        <artifactId>java-design-patterns</artifactId>
+        <version>1.22.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>circuit-breaker</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/App.java b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/App.java
new file mode 100644
index 000000000000..d1d361b16063
--- /dev/null
+++ b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/App.java
@@ -0,0 +1,86 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * The intention of the Circuit Builder pattern is to handle remote failures 
+ * robustly, which is to mean that if a service is dependant on n number of
+ * other services, and m of them fail, we should be able to recover from that
+ * failure by ensuring that the user can still use the services that are actually
+ * functional, and resources are not tied up by uselessly by the services which
+ * are not working. However, we should also be able to detect when any of the m
+ * failing services become operational again, so that we can use it
+ * </p>
+ * <p>
+ * In this example, the circuit breaker pattern is demonstrated by using two services:
+ * {@link MonitoringService} and {@link DelayedService}. The monitoring service
+ * is responsible for calling two services: a local service and a remote service {@link DelayedService}
+ * , and by using the circuit breaker construction we ensure that if the call to
+ * remote service is going to fail, we are going to save our resources and not make the 
+ * function call at all, by wrapping our call to the remote service in the circuit
+ * breaker object.
+ * </p>
+ * <p>
+ * This works as follows: The {@link CircuitBreaker} object can be in one of three
+ * states: <b>Open</b>, <b>Closed</b> and <b>Half-Open</b>, which represents the real
+ * world circuits. If the state is closed (initial), we assume everything is alright
+ * and perform the function call. However, every time the call fails, we note it
+ * and once it crosses a threshold, we set the state to Open, preventing any further
+ * calls to the remote server. Then, after a certain retry period (during which we
+ * expect thee service to recover), we make another call to the remote server and
+ * this state is called the Half-Open state, where it stays till the service is down,
+ * and once it recovers, it goes back to the closed state and the cycle continues.
+ * </p>
+ */
+public class App {
+   
+  private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+    
+   /**
+   * Program entry point
+   * 
+   * @param args command line args
+   */
+  public static void main(String[] args) {
+    //Create an object of monitoring service which makes both local and remote calls
+    var obj = new MonitoringService();
+    //Set the circuit Breaker parameters
+    var circuitBreaker = new CircuitBreaker(3000, 1, 2000 * 1000 * 1000); 
+    var serverStartTime = System.nanoTime();
+    while (true) {
+      LOGGER.info(obj.localResourceResponse());
+      LOGGER.info(obj.remoteResourceResponse(circuitBreaker, serverStartTime));
+      LOGGER.info(circuitBreaker.getState());
+      try {
+        Thread.sleep(5 * 1000); 
+      } catch (InterruptedException e) {
+        LOGGER.error(e.getMessage());
+      }
+    }
+  }
+}
diff --git a/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/CircuitBreaker.java b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/CircuitBreaker.java
new file mode 100644
index 000000000000..ad014f9fdae0
--- /dev/null
+++ b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/CircuitBreaker.java
@@ -0,0 +1,128 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+/**
+ * The circuit breaker class with all configurations
+ */
+public class CircuitBreaker {
+  private final long timeout;
+  private final long retryTimePeriod;
+  long lastFailureTime;
+  int failureCount;
+  private final int failureThreshold;
+  private State state;
+  private final long futureTime = 1000 * 1000 * 1000 * 1000;
+
+  /**
+   * Constructor to create an instance of Circuit Breaker
+   * @param timeout Timeout for the API request. Not necessary for this simple example
+   * @param failureThreshold Number of failures we receive from the depended service before changing state to 'OPEN'
+   * @param retryTimePeriod Time period after which a new request is made to remote service for status check.
+   */
+  CircuitBreaker(long timeout, int failureThreshold, long retryTimePeriod) {
+    // We start in a closed state hoping that everything is fine
+    this.state = State.CLOSED;
+    this.failureThreshold = failureThreshold;
+    // Timeout for the API request. Used to break the calls made to remote resource if it exceeds the limit
+    this.timeout = timeout;
+    this.retryTimePeriod = retryTimePeriod;
+    //An absurd amount of time in future which basically indicates the last failure never happened
+    this.lastFailureTime = System.nanoTime() + futureTime;
+    this.failureCount = 0;
+  }
+    
+  //Reset everything to defaults
+  private void reset() {
+    this.failureCount = 0;
+    this.lastFailureTime = System.nanoTime() + futureTime; 
+    this.state = State.CLOSED;
+  }
+
+  private void recordFailure() {
+    failureCount = failureCount + 1;
+    this.lastFailureTime = System.nanoTime();
+  }
+    
+  protected void setState() {
+    if (failureCount > failureThreshold) { //Then something is wrong with remote service
+      if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
+        //We have waited long enough and should try checking if service is up
+        state = State.HALF_OPEN;
+      } else {
+        //Service would still probably be down
+        state = State.OPEN;
+      }
+    } else {
+      //Everything is working fine
+      state = State.CLOSED;
+    }
+  }
+    
+  public String getState() {
+    return state.name();
+  }
+  
+  /**
+   * Break the circuit beforehand if it is known service is down
+   * Or connect the circuit manually if service comes online before expected
+   * @param state State at which circuit is in
+   */
+  public void setStateForBypass(State state) {
+    this.state = state;
+  }
+   
+  /**
+   * @param serviceToCall The name of the service in String. Can be changed to data URLs in case of web applications
+   * @param serverStartTime Time at which actual server was started which makes calls to this service
+   * @return Value from the remote resource, stale response or a custom exception
+   */
+  public String call(String serviceToCall, long serverStartTime) throws Exception {
+    setState();
+    if (state == State.OPEN) {
+      // return  cached response if no the circuit is in OPEN state
+      return "This is stale response from API";
+    } else {
+        // Make the API request if the circuit is not OPEN
+      if (serviceToCall.equals("delayedService")) {
+        var delayedService = new DelayedService(20);
+        var response = delayedService.response(serverStartTime);
+        //In a real application, this would be run in a thread and the timeout
+        //parameter of the circuit breaker would be utilized to know if service
+        //is working. Here, we simulate that based on server response itself
+        if (response.split(" ")[3].equals("working")) {
+          // Yay!! the API responded fine. Let's reset everything.
+          reset();
+          return response;
+        } else {
+          // Uh-oh!! the call still failed. Let's update that in our records.
+          recordFailure();
+          throw new Exception("Remote service not responding");
+        }
+      } else {
+        throw new Exception("Unknown Service Name");
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/DelayedService.java b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/DelayedService.java
new file mode 100644
index 000000000000..33217b8e721b
--- /dev/null
+++ b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/DelayedService.java
@@ -0,0 +1,61 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.circuitbreaker;
+
+/**
+* This simulates the remote service
+* It responds only after a certain timeout period (default set to 20 seconds)
+*/
+public class DelayedService {
+  private final int delay;
+
+  /**
+   * Constructor to create an instance of DelayedService, which is down for first few seconds
+   * @param delay the delay after which service would behave properly, in seconds
+   */
+  public DelayedService(int delay) {
+    this.delay = delay;
+  }
+
+  public DelayedService() {
+    this.delay = 60;
+  }
+
+  /**
+   * @param serverStartTime Time at which actual server was started which makes calls to this service
+   * @return The state of the service
+   */
+  public String response(long serverStartTime) {
+    var currentTime = System.nanoTime();
+    //Since currentTime and serverStartTime are both in nanoseconds, we convert it to
+    //seconds by diving by 10e9 and ensure floating point division by multiplying it
+    //with 1.0 first. We then check if it is greater or less than specified delay and then
+    //send the reply
+    if ((currentTime - serverStartTime) * 1.0 / (1000 * 1000 * 1000) < delay) {
+      //Can use Thread.sleep() here to block and simulate a hung server
+      return "Delayed service is down";
+    } else {
+      return "Delayed service is working";
+    }
+  }
+}
diff --git a/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/MonitoringService.java b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/MonitoringService.java
new file mode 100644
index 000000000000..e301ff3ca52b
--- /dev/null
+++ b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/MonitoringService.java
@@ -0,0 +1,50 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+/**
+ * The service class which makes local and remote calls
+ * Uses {@link CircuitBreaker} object to ensure remote calls don't use up resources
+ */
+public class MonitoringService {
+
+  //Assumption: Local service won't fail, no need to wrap it in a circuit breaker logic
+  public String localResourceResponse() {
+    return "Local Service is working";
+  }
+
+  /**
+   * Try to get result from remote server
+   * @param circuitBreaker The circuitBreaker object with all parameters
+   * @param serverStartTime Time at which actual server was started which makes calls to this service
+   * @return result from the remote response or exception raised by it.
+   */
+  public String remoteResourceResponse(CircuitBreaker circuitBreaker, long serverStartTime) {
+    try {
+      return circuitBreaker.call("delayedService", serverStartTime);
+    } catch (Exception e) {
+      return e.getMessage();
+    }
+  }
+}
\ No newline at end of file
diff --git a/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/State.java b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/State.java
new file mode 100644
index 000000000000..87982153ccd0
--- /dev/null
+++ b/circuit-breaker/src/main/java/com/iluwatar/circuitbreaker/State.java
@@ -0,0 +1,33 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+/**
+ * Enumeration for states the circuit breaker could be in
+ */
+public enum State {
+        CLOSED,
+        OPEN,
+        HALF_OPEN
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 50e7c7de5439..9e61e716b864 100644
--- a/pom.xml
+++ b/pom.xml
@@ -181,6 +181,7 @@
         <module>bytecode</module>
         <module>leader-election</module>
         <module>data-locality</module>
+        <module>circuit-breaker</module>
 
     </modules>
 


Test patch:
diff --git a/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/CircuitBreakerTest.java b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/CircuitBreakerTest.java
new file mode 100644
index 000000000000..5780e9355c58
--- /dev/null
+++ b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/CircuitBreakerTest.java
@@ -0,0 +1,80 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
+
+/**
+ * 
+ * Circuit Breaker test
+ *
+ */
+public class CircuitBreakerTest {
+
+  //long timeout, int failureThreshold, long retryTimePeriod
+  @Test
+  public void testSetState() {
+    var circuitBreaker = new CircuitBreaker(1,1,100);
+    //Right now, failureCount<failureThreshold, so state should be closed
+    assertEquals(circuitBreaker.getState(), "CLOSED");
+    circuitBreaker.failureCount = 4;
+    circuitBreaker.lastFailureTime = System.nanoTime();
+    circuitBreaker.setState();
+    //Since failureCount>failureThreshold, and lastFailureTime is nearly equal to current time,
+    //state should be half-open
+    assertEquals(circuitBreaker.getState(), "HALF_OPEN");
+    //Since failureCount>failureThreshold, and lastFailureTime is much lesser current time,
+    //state should be open
+    circuitBreaker.lastFailureTime = System.nanoTime() - 1000 * 1000 * 1000 * 1000;
+    circuitBreaker.setState();
+    assertEquals(circuitBreaker.getState(), "OPEN");
+    //Now set it back again to closed to test idempotency
+    circuitBreaker.failureCount = 0;
+    circuitBreaker.setState();
+    assertEquals(circuitBreaker.getState(), "CLOSED");
+  }
+  
+  @Test
+  public void testSetStateForBypass() {
+    var circuitBreaker = new CircuitBreaker(1,1,100);
+    //Right now, failureCount<failureThreshold, so state should be closed
+    //Bypass it and set it to open
+    circuitBreaker.setStateForBypass(State.OPEN);
+    assertEquals(circuitBreaker.getState(), "OPEN");
+  }
+  
+  @Test
+  public void testApiResponses() {
+    var circuitBreaker = new CircuitBreaker(1,1,100);
+    try {
+      //Call with the paramater start_time set to huge amount of time in past so that service 
+      //replies with "Ok". Also, state is CLOSED in start
+      var response = circuitBreaker.call("delayedService", System.nanoTime() - 60 * 1000 * 1000 * 1000);
+      assertEquals(response, "Delayed service is working");
+    } catch (Exception e) {
+      System.out.println(e.getMessage());
+    }
+  }
+}
diff --git a/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/DelayedServiceTest.java b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/DelayedServiceTest.java
new file mode 100644
index 000000000000..7b9c33795144
--- /dev/null
+++ b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/DelayedServiceTest.java
@@ -0,0 +1,42 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
+
+/**
+ * 
+ * Monitoring Service test
+ *
+ */
+public class DelayedServiceTest {
+
+  //Improves code coverage
+  @Test
+  public void testDefaultConstructor() {
+    var obj = new DelayedService();
+    assertEquals(obj.response(System.nanoTime()), "Delayed service is down");
+  }
+}
diff --git a/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/MonitoringServiceTest.java b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/MonitoringServiceTest.java
new file mode 100644
index 000000000000..280da63e5e91
--- /dev/null
+++ b/circuit-breaker/src/test/java/com/iluwatar/circuitbreaker/MonitoringServiceTest.java
@@ -0,0 +1,63 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.circuitbreaker;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
+
+/**
+ * 
+ * Monitoring Service test
+ *
+ */
+public class MonitoringServiceTest {
+
+  //long timeout, int failureThreshold, long retryTimePeriod
+  @Test
+  public void testLocalResponse() {
+    var monitoringService = new MonitoringService();
+    var response = monitoringService.localResourceResponse();
+    assertEquals(response, "Local Service is working");
+  }
+  
+  @Test
+  public void testRemoteResponse() {
+    var monitoringService = new MonitoringService();
+    var circuitBreaker = new CircuitBreaker(1,1,100);
+    //Set time in past to make the server work
+    var serverStartTime = System.nanoTime() / 10;
+    var response = monitoringService.remoteResourceResponse(circuitBreaker, serverStartTime);
+    assertEquals(response, "Delayed service is working");
+  }
+  
+  @Test
+  public void testRemoteResponse2() {
+    MonitoringService monitoringService = new MonitoringService();
+    CircuitBreaker circuitBreaker = new CircuitBreaker(1,1,100);
+    //Set time as current time as initially server fails
+    long serverStartTime = System.nanoTime();
+    String response = monitoringService.remoteResourceResponse(circuitBreaker, serverStartTime);
+    assertEquals(response, "Remote service not responding");
+  }
+}