You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ja...@apache.org on 2023/11/13 13:54:14 UTC

(solr) branch main updated: SOLR-16961 Remove deprecated CircuitBreakerManager in 10.0 (#2059)

This is an automated email from the ASF dual-hosted git repository.

janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new 18bf51ad8d7 SOLR-16961 Remove deprecated CircuitBreakerManager in 10.0 (#2059)
18bf51ad8d7 is described below

commit 18bf51ad8d72fba4f10e94726ee7d0b887baec0e
Author: Jan Høydahl <ja...@apache.org>
AuthorDate: Mon Nov 13 14:54:09 2023 +0100

    SOLR-16961 Remove deprecated CircuitBreakerManager in 10.0 (#2059)
---
 solr/CHANGES.txt                                   |   2 +
 .../solr/handler/ContentStreamHandlerBase.java     |   2 +-
 .../solr/handler/component/SearchHandler.java      |   2 +-
 .../solr/util/circuitbreaker/CircuitBreaker.java   |  56 +++++++---
 .../util/circuitbreaker/CircuitBreakerManager.java | 118 ---------------------
 .../conf/solrconfig-legacy-circuitbreaker.xml      |  97 -----------------
 .../org/apache/solr/util/TestCircuitBreaker.java   |  33 ------
 ...ircuitBreaker.java => TestCircuitBreakers.java} |  79 ++++++++++----
 .../apache/solr/util/TestLegacyCircuitBreaker.java |  38 -------
 .../deployment-guide/pages/circuit-breakers.adoc   |  15 ++-
 .../pages/solrcloud-distributed-requests.adoc      |   1 +
 .../pages/major-changes-in-solr-10.adoc            |   4 +-
 12 files changed, 111 insertions(+), 336 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 8335ed14fdc..c6a7ecb81f1 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -45,6 +45,8 @@ Deprecation Removals
 
 * SOLR-15959: Remove deprecated feature to load solr.xml from ZK (janhoy)
 
+* SOLR-16961: The legacy Circuit Breaker named `CircuitBreakerManager`, is removed. Please use individual Circuit Breaker plugins instead. (janhoy)
+
 * SOLR-17042: Remove deprecated `V2RequestSupport` and associated `SolrRequest` methods `setUseV2` and `setUseBinaryV2`. (Jason Gerlowski)
 
 Dependency Upgrades
diff --git a/solr/core/src/java/org/apache/solr/handler/ContentStreamHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/ContentStreamHandlerBase.java
index f28a7a6a6de..bef772989f4 100644
--- a/solr/core/src/java/org/apache/solr/handler/ContentStreamHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/ContentStreamHandlerBase.java
@@ -139,7 +139,7 @@ public abstract class ContentStreamHandlerBase extends RequestHandlerBase {
         rsp.add(STATUS, FAILURE);
         rsp.setException(
             new SolrException(
-                CircuitBreaker.getErrorCode(trippedCircuitBreakers),
+                CircuitBreaker.getExceptionErrorCode(),
                 "Circuit Breakers tripped " + errorMessage));
         return true;
       }
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java
index 744d6093222..6f831f67714 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java
@@ -385,7 +385,7 @@ public class SearchHandler extends RequestHandlerBase
         rsp.add(STATUS, FAILURE);
         rsp.setException(
             new SolrException(
-                CircuitBreaker.getErrorCode(trippedCircuitBreakers),
+                CircuitBreaker.getExceptionErrorCode(),
                 "Circuit Breakers tripped " + errorMessage));
         return true;
       }
diff --git a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
index 78841cceaf7..1bba4de7c6a 100644
--- a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
+++ b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
@@ -44,6 +44,9 @@ import org.apache.solr.util.plugin.NamedListInitializedPlugin;
  * @lucene.experimental
  */
 public abstract class CircuitBreaker implements NamedListInitializedPlugin, Closeable {
+  public static final String SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE =
+      "solr.circuitbreaker.errorcode";
+  private static SolrException.ErrorCode errorCode = resolveExceptionErrorCode();
   // Only query requests are checked by default
   private Set<SolrRequestType> requestTypes = Set.of(SolrRequestType.QUERY);
   private final List<SolrRequestType> SUPPORTED_TYPES =
@@ -54,7 +57,10 @@ public abstract class CircuitBreaker implements NamedListInitializedPlugin, Clos
     SolrPluginUtils.invokeSetters(this, args);
   }
 
-  public CircuitBreaker() {}
+  public CircuitBreaker() {
+    // Early abort if custom error code system property is wrong
+    errorCode = resolveExceptionErrorCode();
+  }
 
   /** Check if circuit breaker is tripped. */
   public abstract boolean isTripped();
@@ -62,6 +68,38 @@ public abstract class CircuitBreaker implements NamedListInitializedPlugin, Clos
   /** Get error message when the circuit breaker triggers */
   public abstract String getErrorMessage();
 
+  /**
+   * Get http error code, defaults to 429 (TOO_MANY_REQUESTS) but can be overridden with system
+   * property {@link #SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE}
+   */
+  public static SolrException.ErrorCode getExceptionErrorCode() {
+    return errorCode;
+  }
+
+  private static SolrException.ErrorCode resolveExceptionErrorCode() {
+    int intCode = SolrException.ErrorCode.TOO_MANY_REQUESTS.code;
+    String strCode = System.getProperty(SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
+    if (strCode != null) {
+      try {
+        intCode = Integer.parseInt(strCode);
+      } catch (NumberFormatException nfe) {
+        intCode = SolrException.ErrorCode.UNKNOWN.code;
+      }
+    }
+    SolrException.ErrorCode errorCode = SolrException.ErrorCode.getErrorCode(intCode);
+    if (errorCode != SolrException.ErrorCode.UNKNOWN) {
+      return errorCode;
+    } else {
+      throw new SolrException(
+          SolrException.ErrorCode.SERVER_ERROR,
+          String.format(
+              Locale.ROOT,
+              "Invalid error code %s specified for circuit breaker system property %s.",
+              strCode,
+              SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE));
+    }
+  }
+
   @Override
   public void close() throws IOException {
     // Nothing to do by default
@@ -94,20 +132,4 @@ public abstract class CircuitBreaker implements NamedListInitializedPlugin, Clos
   public Set<SolrRequestType> getRequestTypes() {
     return requestTypes;
   }
-
-  /**
-   * Return the proper error code to use in exception. For legacy use of {@link CircuitBreaker} we
-   * return 503 for backward compatibility, else return 429.
-   *
-   * @deprecated Remove in 10.0
-   */
-  @Deprecated(since = "9.4")
-  public static SolrException.ErrorCode getErrorCode(List<CircuitBreaker> trippedCircuitBreakers) {
-    if (trippedCircuitBreakers != null
-        && trippedCircuitBreakers.stream().anyMatch(cb -> cb instanceof CircuitBreakerManager)) {
-      return SolrException.ErrorCode.SERVICE_UNAVAILABLE;
-    } else {
-      return SolrException.ErrorCode.TOO_MANY_REQUESTS;
-    }
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerManager.java b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerManager.java
deleted file mode 100644
index 3ca0c760a86..00000000000
--- a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerManager.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.solr.util.circuitbreaker;
-
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import org.apache.solr.common.util.NamedList;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Single CircuitBreaker that registers both a Memory and a LoadAverage CircuitBreaker. This is only
- * for backward compatibility with the 9.x versions prior to 9.4.
- *
- * @deprecated Use individual Circuit Breakers instead
- */
-@Deprecated(since = "9.4")
-public class CircuitBreakerManager extends CircuitBreaker {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-  private boolean cpuEnabled;
-  private boolean memEnabled;
-  private int memThreshold = 100;
-  private int cpuThreshold = 100;
-  private MemoryCircuitBreaker memCB;
-  private LoadAverageCircuitBreaker cpuCB;
-
-  public CircuitBreakerManager() {
-    super();
-  }
-
-  @Override
-  public boolean isTripped() {
-    return (memEnabled && memCB.isTripped()) || (cpuEnabled && cpuCB.isTripped());
-  }
-
-  @Override
-  public String getErrorMessage() {
-    StringBuilder sb = new StringBuilder();
-    if (memEnabled) {
-      sb.append(memCB.getErrorMessage());
-    }
-    if (memEnabled && cpuEnabled) {
-      sb.append("\n");
-    }
-    if (cpuEnabled) {
-      sb.append(cpuCB.getErrorMessage());
-    }
-    return sb.toString();
-  }
-
-  @Override
-  public void init(NamedList<?> args) {
-    super.init(args);
-    log.warn("CircuitBreakerManager is deprecated. Use individual Circuit Breakers instead");
-    if (memEnabled) {
-      memCB = new MemoryCircuitBreaker();
-      memCB.setThreshold(memThreshold);
-    }
-    if (cpuEnabled) {
-      // In SOLR-15056 CPUCircuitBreaker was renamed to LoadAverageCircuitBreaker, need back-compat
-      cpuCB = new LoadAverageCircuitBreaker();
-      cpuCB.setThreshold(cpuThreshold);
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    try {
-      if (memEnabled) {
-        memCB.close();
-      }
-    } finally {
-      if (cpuEnabled) {
-        cpuCB.close();
-      }
-    }
-  }
-
-  // The methods below will be called by super class during init
-  public void setMemEnabled(String enabled) {
-    this.memEnabled = Boolean.getBoolean(enabled);
-  }
-
-  public void setMemThreshold(int threshold) {
-    this.memThreshold = threshold;
-  }
-
-  public void setMemThreshold(String threshold) {
-    this.memThreshold = Integer.parseInt(threshold);
-  }
-
-  public void setCpuEnabled(String enabled) {
-    this.cpuEnabled = Boolean.getBoolean(enabled);
-  }
-
-  public void setCpuThreshold(int threshold) {
-    this.cpuThreshold = threshold;
-  }
-
-  public void setCpuThreshold(String threshold) {
-    this.cpuThreshold = Integer.parseInt(threshold);
-  }
-}
diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-legacy-circuitbreaker.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-legacy-circuitbreaker.xml
deleted file mode 100644
index fb00756b86c..00000000000
--- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-legacy-circuitbreaker.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" ?>
-
-<!--
- 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.
--->
-
-<config>
-  <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
-  <dataDir>${solr.data.dir:}</dataDir>
-  <xi:include href="solrconfig.snippet.randomindexconfig.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
-  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
-  <schemaFactory class="ClassicIndexSchemaFactory"/>
-  <requestHandler name="/select" class="solr.SearchHandler" />
-
-  <query>
-    <!-- Maximum number of clauses in a boolean query... can affect
-        range or wildcard queries that expand to big boolean
-        queries.  An exception is thrown if exceeded.
-    -->
-    <maxBooleanClauses>${solr.max.booleanClauses:1024}</maxBooleanClauses>
-
-    <!-- Cache specification for Filters or DocSets - unordered set of *all* documents
-         that match a particular query.
-      -->
-    <filterCache
-      enabled="${filterCache.enabled}"
-      size="512"
-      initialSize="512"
-      autowarmCount="2"/>
-
-    <queryResultCache
-      enabled="${queryResultCache.enabled}"
-      size="512"
-      initialSize="512"
-      autowarmCount="2"/>
-
-    <documentCache
-      enabled="${documentCache.enabled}"
-      size="512"
-      initialSize="512"
-      autowarmCount="0"/>
-
-    <cache
-      name="user_defined_cache_XXX"
-      enabled="${user_defined_cache_XXX.enabled:false}"
-      />
-    <cache
-      name="user_defined_cache_ZZZ"
-      enabled="${user_defined_cache_ZZZ.enabled:false}"
-      />
-
-
-
-    <!-- If true, stored fields that are not requested will be loaded lazily.
-    -->
-    <enableLazyFieldLoading>true</enableLazyFieldLoading>
-
-    <queryResultWindowSize>10</queryResultWindowSize>
-
-    <!-- boolToFilterOptimizer converts boolean clauses with zero boost
-         into cached filters if the number of docs selected by the clause exceeds
-         the threshold (represented as a fraction of the total index)
-    -->
-    <boolTofilterOptimizer enabled="false" cacheSize="32" threshold=".05"/>
-
-  </query>
-
-  <!-- Legacy config used in 9.x.
-   TODO: Remove this file in 10.0
-   -->
-  <circuitBreaker class="solr.CircuitBreakerManager">
-    <str name="memEnabled">true</str>
-    <str name="memThreshold">75</str>
-    <str name="cpuEnabled">true</str>
-    <str name="cpuThreshold">75</str>
-  </circuitBreaker>
-
-  <initParams path="/select">
-    <lst name="defaults">
-      <str name="df">text</str>
-    </lst>
-  </initParams>
-
-</config>
diff --git a/solr/core/src/test/org/apache/solr/util/TestCircuitBreaker.java b/solr/core/src/test/org/apache/solr/util/TestCircuitBreaker.java
deleted file mode 100644
index 37500b4126f..00000000000
--- a/solr/core/src/test/org/apache/solr/util/TestCircuitBreaker.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.solr.util;
-
-import org.junit.BeforeClass;
-
-/** Tests the pluggable circuit breaker implementation. The actual tests are in base class. */
-public class TestCircuitBreaker extends BaseTestCircuitBreaker {
-  @BeforeClass
-  public static void setUpClass() throws Exception {
-    System.setProperty("filterCache.enabled", "false");
-    System.setProperty("queryResultCache.enabled", "false");
-    System.setProperty("documentCache.enabled", "true");
-
-    initCore("solrconfig-pluggable-circuitbreaker.xml", "schema.xml");
-    BaseTestCircuitBreaker.indexDocs();
-  }
-}
diff --git a/solr/core/src/test/org/apache/solr/util/BaseTestCircuitBreaker.java b/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
similarity index 82%
rename from solr/core/src/test/org/apache/solr/util/BaseTestCircuitBreaker.java
rename to solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
index 880d10d162a..aebc5483a15 100644
--- a/solr/core/src/test/org/apache/solr/util/BaseTestCircuitBreaker.java
+++ b/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
@@ -34,19 +34,29 @@ import org.apache.solr.common.util.SolrNamedThreadFactory;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.util.circuitbreaker.CPUCircuitBreaker;
 import org.apache.solr.util.circuitbreaker.CircuitBreaker;
-import org.apache.solr.util.circuitbreaker.CircuitBreakerManager;
 import org.apache.solr.util.circuitbreaker.CircuitBreakerRegistry;
 import org.apache.solr.util.circuitbreaker.LoadAverageCircuitBreaker;
 import org.apache.solr.util.circuitbreaker.MemoryCircuitBreaker;
 import org.hamcrest.MatcherAssert;
 import org.junit.After;
+import org.junit.BeforeClass;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class BaseTestCircuitBreaker extends SolrTestCaseJ4 {
+public class TestCircuitBreakers extends SolrTestCaseJ4 {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   private static final CircuitBreaker dummyMemBreaker = new MemoryCircuitBreaker();
-  private static final CircuitBreaker dummyCBManager = new CircuitBreakerManager();
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    System.setProperty("filterCache.enabled", "false");
+    System.setProperty("queryResultCache.enabled", "false");
+    System.setProperty("documentCache.enabled", "true");
+    System.clearProperty(CircuitBreaker.SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
+
+    initCore("solrconfig-pluggable-circuitbreaker.xml", "schema.xml");
+    indexDocs();
+  }
 
   protected static void indexDocs() {
     removeAllExistingCircuitBreakers();
@@ -67,7 +77,7 @@ public abstract class BaseTestCircuitBreaker extends SolrTestCaseJ4 {
   public void tearDown() throws Exception {
     super.tearDown();
     dummyMemBreaker.close();
-    dummyCBManager.close();
+    removeAllExistingCircuitBreakers();
   }
 
   @After
@@ -75,14 +85,34 @@ public abstract class BaseTestCircuitBreaker extends SolrTestCaseJ4 {
     removeAllExistingCircuitBreakers();
   }
 
-  public void testCBAlwaysTrips() {
-    removeAllExistingCircuitBreakers();
-
-    CircuitBreaker circuitBreaker = new MockCircuitBreaker(true);
-
-    h.getCore().getCircuitBreakerRegistry().register(circuitBreaker);
-
-    expectThrows(SolrException.class, () -> h.query(req("name:\"john smith\"")));
+  public void testCBAlwaysTripsWithCorrectCode() {
+    synchronized (this) {
+      List.of(
+              -1,
+              SolrException.ErrorCode.TOO_MANY_REQUESTS.code,
+              SolrException.ErrorCode.SERVICE_UNAVAILABLE.code,
+              SolrException.ErrorCode.BAD_REQUEST.code)
+          .forEach(
+              code -> {
+                removeAllExistingCircuitBreakers();
+                if (code > 0) {
+                  System.setProperty(
+                      CircuitBreaker.SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE, String.valueOf(code));
+                }
+                CircuitBreaker circuitBreaker = new MockCircuitBreaker(true);
+                h.getCore().getCircuitBreakerRegistry().register(circuitBreaker);
+                SolrException ex =
+                    expectThrows(
+                        SolrException.class,
+                        () -> {
+                          h.query(req("name:\"john smith\""));
+                        });
+                assertEquals(
+                    (code == -1) ? SolrException.ErrorCode.TOO_MANY_REQUESTS.code : code,
+                    ex.code());
+                System.clearProperty(CircuitBreaker.SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
+              });
+    }
   }
 
   public void testGlobalCBAlwaysTrips() {
@@ -99,6 +129,22 @@ public abstract class BaseTestCircuitBreaker extends SolrTestCaseJ4 {
         });
   }
 
+  @SuppressWarnings("resource")
+  public void testCBAlwaysTripsInvalidErrorCodeSysProp() {
+    synchronized (this) {
+      List.of("foo", 123, 999, 888)
+          .forEach(
+              code -> {
+                System.setProperty(
+                    CircuitBreaker.SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE, String.valueOf(code));
+                SolrException ex =
+                    expectThrows(SolrException.class, () -> new MockCircuitBreaker(true));
+                assertTrue(ex.getMessage().contains("Invalid error code"));
+                System.clearProperty(CircuitBreaker.SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
+              });
+    }
+  }
+
   public void testCBFakeMemoryPressure() throws Exception {
     removeAllExistingCircuitBreakers();
 
@@ -253,15 +299,6 @@ public abstract class BaseTestCircuitBreaker extends SolrTestCaseJ4 {
         "//lst[@name='process']/double[@name='time']");
   }
 
-  public void testErrorCode() throws Exception {
-    assertEquals(
-        SolrException.ErrorCode.SERVICE_UNAVAILABLE,
-        CircuitBreaker.getErrorCode(List.of(dummyCBManager)));
-    assertEquals(
-        SolrException.ErrorCode.TOO_MANY_REQUESTS,
-        CircuitBreaker.getErrorCode(List.of(dummyMemBreaker)));
-  }
-
   private static void removeAllExistingCircuitBreakers() {
     try {
       h.getCore().getCircuitBreakerRegistry().deregisterAll();
diff --git a/solr/core/src/test/org/apache/solr/util/TestLegacyCircuitBreaker.java b/solr/core/src/test/org/apache/solr/util/TestLegacyCircuitBreaker.java
deleted file mode 100644
index cd4cc499a36..00000000000
--- a/solr/core/src/test/org/apache/solr/util/TestLegacyCircuitBreaker.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.solr.util;
-
-import org.junit.BeforeClass;
-
-/**
- * Tests the original circuit breaker configuration format, which was not configurable.
- *
- * @deprecated Remove in 10.0
- */
-@Deprecated(since = "9.4")
-public class TestLegacyCircuitBreaker extends BaseTestCircuitBreaker {
-  @BeforeClass
-  public static void setUpClass() throws Exception {
-    System.setProperty("filterCache.enabled", "false");
-    System.setProperty("queryResultCache.enabled", "false");
-    System.setProperty("documentCache.enabled", "true");
-
-    initCore("solrconfig-legacy-circuitbreaker.xml", "schema.xml");
-    BaseTestCircuitBreaker.indexDocs();
-  }
-}
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/circuit-breakers.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/circuit-breakers.adoc
index f9f535c6005..47da5f386fe 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/circuit-breakers.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/circuit-breakers.adoc
@@ -29,22 +29,19 @@ It is up to the client to handle this error and potentially build retry logic as
 In a sharded collection, when a circuit breaker trips on one shard, the entire query will fail,
 even if the other shard requests succeed. This will multiply the failures seen by the end users.
 Setting the `shards.tolerant=true` parameter on requests can help with graceful degradation when
-circuit breaker thresholds are reached on some nodes. See the <<shards.tolerant Parameter>> for details.
+circuit breaker thresholds are reached on some nodes. See <<solrcloud-distributed-requests#shards-tolerant-parameter,`shards.tolerant`>> for details.
 
 == Circuit Breaker Configurations
 All circuit breaker configurations are listed as independent `<circuitBreaker>` entries in `solrconfig.xml` as shown below.
-A circuit breaker can register itself to trip for query requests and/or update requests. By default only search requests are affected. A user may register multiple circuit breakers of the same type with different thresholds for each request type.
+A circuit breaker can register itself to trip for query requests and/or update requests. By default, only search requests are affected. A user may register multiple circuit breakers of the same type with different thresholds for each request type.
 
-== Currently Supported Circuit Breakers
-
-[NOTE]
+[TIP]
 ====
-The legacy configuration syntax using `CircuitBreakerManager` is deprecated as of Solr 9.4, but will
-continue to work. The "CPU" circuit breaker used by this legacy plugin when configuring a `cpuThreshold`
-is actually the `LoadAverageCircuitBreaker` described below. Also, the `CircuitBreakerManager` will
-return a HTTP 503 code instead of the HTTP 429 code used by the new circuit breakers.
+HTTP error code from circuit breakers is configurable with java system property `solr.circuitbreaker.errorcode`.
 ====
 
+== Currently Supported Circuit Breakers
+
 === JVM Heap Usage
 
 This circuit breaker tracks JVM heap memory usage and rejects incoming requests with a 429 error code if the heap usage exceeds a configured percentage of maximum heap allocated to the JVM (-Xmx).
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/solrcloud-distributed-requests.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/solrcloud-distributed-requests.adoc
index b8af8e821a2..68cf6070e6a 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/solrcloud-distributed-requests.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solrcloud-distributed-requests.adoc
@@ -60,6 +60,7 @@ A `zkConnected` header is included in every search response indicating if the no
 To prevent stale or incorrect results in the event that the request-serving node can't communicate with ZooKeeper, set the <<shards-tolerant-parameter,`shards.tolerant`>> parameter to `requireZkConnected`.
 This will cause requests to fail rather than setting a `zkConnected` header to `false`.
 
+[#shards-tolerant-parameter]
 === shards.tolerant Parameter
 
 In the event that one or more shards queried are unavailable, then Solr's default behavior is to fail the request.
diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index d12f894eda9..e407ab04f64 100644
--- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -45,4 +45,6 @@ has been removed. Please use `-Dsolr.hiddenSysProps` or the envVar `SOLR_HIDDEN_
 Please see `-Dsolr.redaction.system.pattern`, which allows users to provide a pattern to match sysProps that should be redacted for sensitive information,
 has been removed. Please use `-Dsolr.hiddenSysProps` or the envVar `SOLR_HIDDEN_SYS_PROPS` instead.
 
-* The node configuration file `/solr.xml` can no longer be loaded from Zookeeper. Solr startup will fail if it is present.
\ No newline at end of file
+* The node configuration file `/solr.xml` can no longer be loaded from Zookeeper. Solr startup will fail if it is present.
+
+* The legacy Circuit Breaker named `CircuitBreakerManager`, is removed. Please use individual Circuit Breaker plugins instead.
\ No newline at end of file