/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.lang3.concurrent; import java.util.concurrent.atomic.AtomicLong; /** * A simple implementation of the Circuit Breaker pattern * that opens if the requested increment amount is greater than a given threshold. * *
* It contains an internal counter that starts in zero, and each call increments the counter by a given amount. * If the threshold is zero, the circuit breaker will be in a permanent open state. *
* ** An example of use case could be a memory circuit breaker. *
* ** long threshold = 10L; * ThresholdCircuitBreaker breaker = new ThresholdCircuitBreaker(10L); * ... * public void handleRequest(Request request) { * long memoryUsed = estimateMemoryUsage(request); * if (breaker.incrementAndCheckState(memoryUsed)) { * // actually handle this request * } else { * // do something else, e.g. send an error code * } * } ** *
#Thread safe#
* @since 3.5 */ public class ThresholdCircuitBreaker extends AbstractCircuitBreakerResets the internal counter back to its initial value (zero).
*/ @Override public void close() { super.close(); this.used.set(INITIAL_COUNT); } /** * {@inheritDoc} * *If the threshold is zero, the circuit breaker will be in a permanent open state.
*/ @Override public boolean incrementAndCheckState(final Long increment) { if (threshold == 0) { open(); } final long used = this.used.addAndGet(increment); if (used > threshold) { open(); } return checkState(); } }