/** Reset all breaker settings back to their defaults */ private void reset() { logger.info("--> resetting breaker settings"); Settings resetSettings = Settings.builder() .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING .getDefaultRaw(null)) .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(), HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING .getDefaultRaw(null)) .put( HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getDefaultRaw( null)) .put( HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(), 1.0) .put( HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_LIMIT_SETTING .getKey(), HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_LIMIT_SETTING .getDefaultRaw(null)) .put( HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_OVERHEAD_SETTING .getKey(), 1.0) .put( HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getDefaultRaw( null)) .build(); assertAcked( client().admin().cluster().prepareUpdateSettings().setTransientSettings(resetSettings)); }
/** * Test that a breaker correctly redistributes to a different breaker, in this case, the fielddata * breaker borrows space from the request breaker */ @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/18325") public void testParentChecking() throws Exception { if (noopBreakerUsed()) { logger.info("--> noop breakers used, skipping test"); return; } assertAcked( prepareCreate( "cb-test", 1, Settings.builder().put(SETTING_NUMBER_OF_REPLICAS, between(0, 1))) .addMapping("type", "test", "type=text,fielddata=true")); Client client = client(); // index some different terms so we have some field data for loading int docCount = scaledRandomIntBetween(300, 1000); List<IndexRequestBuilder> reqs = new ArrayList<>(); for (long id = 0; id < docCount; id++) { reqs.add( client .prepareIndex("cb-test", "type", Long.toString(id)) .setSource("test", "value" + id)); } indexRandom(true, reqs); Settings resetSettings = Settings.builder() .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "10b") .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(), 1.0) .build(); assertAcked( client.admin().cluster().prepareUpdateSettings().setTransientSettings(resetSettings)); // Perform a search to load field data for the "test" field try { client .prepareSearch("cb-test") .setQuery(matchAllQuery()) .addSort("test", SortOrder.DESC) .get(); fail("should have thrown an exception"); } catch (Exception e) { String errMsg = "[fielddata] Data too large, data for [test] would be larger than limit of [10/10b]"; assertThat( "Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg)); } assertFailures( client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC), RestStatus.INTERNAL_SERVER_ERROR, containsString("Data too large, data for [test] would be larger than limit of [10/10b]")); reset(); // Adjust settings so the parent breaker will fail, but neither the fielddata breaker nor the // node request breaker will fail resetSettings = Settings.builder() .put( HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "500b") .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "90%") .put( HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(), 1.0) .build(); client .admin() .cluster() .prepareUpdateSettings() .setTransientSettings(resetSettings) .execute() .actionGet(); // Perform a search to load field data for the "test" field try { client .prepareSearch("cb-test") .setQuery(matchAllQuery()) .addSort("test", SortOrder.DESC) .get(); fail("should have thrown an exception"); } catch (Exception e) { final Throwable cause = ExceptionsHelper.unwrap(e, CircuitBreakingException.class); assertNotNull("CircuitBreakingException is not the cause of " + e, cause); String errMsg = "would be larger than limit of [500/500b]]"; assertThat( "Exception: [" + cause.toString() + "] should contain a CircuitBreakingException", cause.toString(), startsWith("CircuitBreakingException[[parent] Data too large")); assertThat( "Exception: [" + cause.toString() + "] should contain a CircuitBreakingException", cause.toString(), endsWith(errMsg)); } finally { // reset before teardown as it requires properly set up breakers reset(); } }