Skip to content

Commit e29b972

Browse files
committed
Revert "Make CBE message creation more robust (#87687) (#87874)"
This reverts commit 4a6e16c.
1 parent 4a6e16c commit e29b972

File tree

5 files changed

+55
-228
lines changed

5 files changed

+55
-228
lines changed

docs/changelog/87687.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

server/src/main/java/org/elasticsearch/indices/breaker/CircuitBreakerStats.java

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,43 +77,33 @@ public double getOverhead() {
7777
@Override
7878
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
7979
builder.startObject(name.toLowerCase(Locale.ROOT));
80-
addBytesFieldsSafe(builder, limit, Fields.LIMIT, Fields.LIMIT_HUMAN);
81-
addBytesFieldsSafe(builder, estimated, Fields.ESTIMATED, Fields.ESTIMATED_HUMAN);
80+
builder.field(Fields.LIMIT, limit);
81+
builder.field(Fields.LIMIT_HUMAN, new ByteSizeValue(limit));
82+
builder.field(Fields.ESTIMATED, estimated);
83+
builder.field(Fields.ESTIMATED_HUMAN, new ByteSizeValue(estimated));
8284
builder.field(Fields.OVERHEAD, overhead);
8385
builder.field(Fields.TRIPPED_COUNT, trippedCount);
8486
builder.endObject();
8587
return builder;
8688
}
8789

88-
private void addBytesFieldsSafe(XContentBuilder builder, long bytes, String rawFieldName, String humanFieldName) throws IOException {
89-
builder.field(rawFieldName, bytes);
90-
if (0 <= bytes) {
91-
builder.field(humanFieldName, new ByteSizeValue(bytes));
92-
} else {
93-
// Something's definitely wrong, maybe a breaker was freed twice? Still, we're just writing out stats here, so we should keep
94-
// going if we're running in production.
95-
assert HierarchyCircuitBreakerService.permitNegativeValues : this;
96-
// noinspection ResultOfMethodCallIgnored - we call toString() to log a warning
97-
toString();
98-
builder.field(humanFieldName, "");
99-
}
100-
}
101-
10290
@Override
10391
public String toString() {
104-
final var stringBuilder = new StringBuilder();
105-
stringBuilder.append("[");
106-
stringBuilder.append(this.name);
107-
stringBuilder.append(",limit=");
108-
HierarchyCircuitBreakerService.appendBytesSafe(stringBuilder, this.limit);
109-
stringBuilder.append(",estimated=");
110-
HierarchyCircuitBreakerService.appendBytesSafe(stringBuilder, this.estimated);
111-
stringBuilder.append(",overhead=");
112-
stringBuilder.append(this.overhead);
113-
stringBuilder.append(",tripped=");
114-
stringBuilder.append(this.trippedCount);
115-
stringBuilder.append("]");
116-
return stringBuilder.toString();
92+
return "["
93+
+ this.name
94+
+ ",limit="
95+
+ this.limit
96+
+ "/"
97+
+ new ByteSizeValue(this.limit)
98+
+ ",estimated="
99+
+ this.estimated
100+
+ "/"
101+
+ new ByteSizeValue(this.estimated)
102+
+ ",overhead="
103+
+ this.overhead
104+
+ ",tripped="
105+
+ this.trippedCount
106+
+ "]";
117107
}
118108

119109
static final class Fields {

server/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java

Lines changed: 36 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
import java.util.Map;
3636
import java.util.concurrent.atomic.AtomicLong;
3737
import java.util.concurrent.locks.ReentrantLock;
38-
import java.util.function.BiConsumer;
3938
import java.util.function.Function;
4039
import java.util.function.LongSupplier;
40+
import java.util.stream.Collectors;
4141

4242
import static org.elasticsearch.core.Strings.format;
4343
import static org.elasticsearch.indices.breaker.BreakerSettings.CIRCUIT_BREAKER_LIMIT_SETTING;
@@ -397,78 +397,47 @@ public void checkParentLimit(long newBytesReserved, String label) throws Circuit
397397
long parentLimit = this.parentSettings.getLimit();
398398
if (memoryUsed.totalUsage > parentLimit && overLimitStrategy.overLimit(memoryUsed).totalUsage > parentLimit) {
399399
this.parentTripCount.incrementAndGet();
400-
final String messageString = buildParentTripMessage(
401-
newBytesReserved,
402-
label,
403-
memoryUsed,
404-
parentLimit,
405-
this.trackRealMemoryUsage,
406-
this.breakers
400+
final StringBuilder message = new StringBuilder(
401+
"[parent] Data too large, data for ["
402+
+ label
403+
+ "]"
404+
+ " would be ["
405+
+ memoryUsed.totalUsage
406+
+ "/"
407+
+ new ByteSizeValue(memoryUsed.totalUsage)
408+
+ "]"
409+
+ ", which is larger than the limit of ["
410+
+ parentLimit
411+
+ "/"
412+
+ new ByteSizeValue(parentLimit)
413+
+ "]"
407414
);
415+
if (this.trackRealMemoryUsage) {
416+
final long realUsage = memoryUsed.baseUsage;
417+
message.append(", real usage: [");
418+
message.append(realUsage);
419+
message.append("/");
420+
message.append(new ByteSizeValue(realUsage));
421+
message.append("], new bytes reserved: [");
422+
message.append(newBytesReserved);
423+
message.append("/");
424+
message.append(new ByteSizeValue(newBytesReserved));
425+
message.append("]");
426+
}
427+
message.append(", usages [");
428+
message.append(this.breakers.entrySet().stream().map(e -> {
429+
final CircuitBreaker breaker = e.getValue();
430+
final long breakerUsed = (long) (breaker.getUsed() * breaker.getOverhead());
431+
return e.getKey() + "=" + breakerUsed + "/" + new ByteSizeValue(breakerUsed);
432+
}).collect(Collectors.joining(", ")));
433+
message.append("]");
408434
// derive durability of a tripped parent breaker depending on whether the majority of memory tracked by
409435
// child circuit breakers is categorized as transient or permanent.
410436
CircuitBreaker.Durability durability = memoryUsed.transientChildUsage >= memoryUsed.permanentChildUsage
411437
? CircuitBreaker.Durability.TRANSIENT
412438
: CircuitBreaker.Durability.PERMANENT;
413-
logger.debug(() -> format("%s", messageString));
414-
throw new CircuitBreakingException(messageString, memoryUsed.totalUsage, parentLimit, durability);
415-
}
416-
}
417-
418-
// exposed for tests
419-
static String buildParentTripMessage(
420-
long newBytesReserved,
421-
String label,
422-
MemoryUsage memoryUsed,
423-
long parentLimit,
424-
boolean trackRealMemoryUsage,
425-
Map<String, CircuitBreaker> breakers
426-
) {
427-
final var message = new StringBuilder();
428-
message.append("[parent] Data too large, data for [");
429-
message.append(label);
430-
message.append("] would be [");
431-
appendBytesSafe(message, memoryUsed.totalUsage);
432-
message.append("], which is larger than the limit of [");
433-
appendBytesSafe(message, parentLimit);
434-
message.append("]");
435-
if (trackRealMemoryUsage) {
436-
final long realUsage = memoryUsed.baseUsage;
437-
message.append(", real usage: [");
438-
appendBytesSafe(message, realUsage);
439-
message.append("], new bytes reserved: [");
440-
appendBytesSafe(message, newBytesReserved);
441-
message.append("]");
442-
}
443-
message.append(", usages [");
444-
breakers.forEach(new BiConsumer<>() {
445-
private boolean first = true;
446-
447-
@Override
448-
public void accept(String key, CircuitBreaker breaker) {
449-
if (first) {
450-
first = false;
451-
} else {
452-
message.append(", ");
453-
}
454-
message.append(key).append("=");
455-
appendBytesSafe(message, (long) (breaker.getUsed() * breaker.getOverhead()));
456-
}
457-
});
458-
message.append("]");
459-
return message.toString();
460-
}
461-
462-
static void appendBytesSafe(StringBuilder stringBuilder, long bytes) {
463-
stringBuilder.append(bytes);
464-
if (bytes >= 0) {
465-
stringBuilder.append("/");
466-
stringBuilder.append(new ByteSizeValue(bytes));
467-
} else {
468-
// Something's definitely wrong, maybe a breaker was freed twice? Still, we're just creating an exception message here, so we
469-
// should keep going if we're running in production.
470-
logger.error("negative value in circuit breaker: {}", stringBuilder);
471-
assert permitNegativeValues : stringBuilder.toString();
439+
logger.debug(() -> format("%s", message.toString()));
440+
throw new CircuitBreakingException(message.toString(), memoryUsed.totalUsage, parentLimit, durability);
472441
}
473442
}
474443

@@ -667,7 +636,4 @@ TimeValue getLockTimeout() {
667636
return lockTimeout;
668637
}
669638
}
670-
671-
// exposed for testing
672-
static boolean permitNegativeValues = false;
673639
}

server/src/test/java/org/elasticsearch/indices/breaker/CircuitBreakerStatsTests.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

server/src/test/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerServiceTests.java

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.elasticsearch.common.breaker.ChildMemoryCircuitBreaker;
1212
import org.elasticsearch.common.breaker.CircuitBreaker;
1313
import org.elasticsearch.common.breaker.CircuitBreakingException;
14-
import org.elasticsearch.common.breaker.NoopCircuitBreaker;
1514
import org.elasticsearch.common.settings.ClusterSettings;
1615
import org.elasticsearch.common.settings.Settings;
1716
import org.elasticsearch.common.unit.ByteSizeUnit;
@@ -26,7 +25,6 @@
2625
import java.util.Arrays;
2726
import java.util.Collections;
2827
import java.util.List;
29-
import java.util.Map;
3028
import java.util.concurrent.BrokenBarrierException;
3129
import java.util.concurrent.CountDownLatch;
3230
import java.util.concurrent.CyclicBarrier;
@@ -48,7 +46,6 @@
4846
import static org.hamcrest.Matchers.lessThanOrEqualTo;
4947
import static org.hamcrest.Matchers.not;
5048
import static org.hamcrest.Matchers.nullValue;
51-
import static org.hamcrest.Matchers.oneOf;
5249
import static org.hamcrest.Matchers.sameInstance;
5350

5451
public class HierarchyCircuitBreakerServiceTests extends ESTestCase {
@@ -876,77 +873,4 @@ public void testApplySettingForUpdatingUseRealMemory() {
876873
);
877874
}
878875
}
879-
880-
public void testBuildParentTripMessage() {
881-
class TestChildCircuitBreaker extends NoopCircuitBreaker {
882-
private final long used;
883-
884-
TestChildCircuitBreaker(long used) {
885-
super("child");
886-
this.used = used;
887-
}
888-
889-
@Override
890-
public long getUsed() {
891-
return used;
892-
}
893-
894-
@Override
895-
public double getOverhead() {
896-
return 1.0;
897-
}
898-
}
899-
900-
assertThat(
901-
HierarchyCircuitBreakerService.buildParentTripMessage(
902-
1L,
903-
"test",
904-
new HierarchyCircuitBreakerService.MemoryUsage(2L, 3L, 4L, 5L),
905-
6L,
906-
false,
907-
Map.of("child", new TestChildCircuitBreaker(7L), "otherChild", new TestChildCircuitBreaker(8L))
908-
),
909-
oneOf(
910-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
911-
+ "usages [child=7/7b, otherChild=8/8b]",
912-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
913-
+ "usages [otherChild=8/8b, child=7/7b]"
914-
)
915-
);
916-
917-
assertThat(
918-
HierarchyCircuitBreakerService.buildParentTripMessage(
919-
1L,
920-
"test",
921-
new HierarchyCircuitBreakerService.MemoryUsage(2L, 3L, 4L, 5L),
922-
6L,
923-
true,
924-
Map.of()
925-
),
926-
equalTo(
927-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
928-
+ "real usage: [2/2b], new bytes reserved: [1/1b], usages []"
929-
)
930-
);
931-
932-
try {
933-
HierarchyCircuitBreakerService.permitNegativeValues = true;
934-
assertThat(
935-
HierarchyCircuitBreakerService.buildParentTripMessage(
936-
-1L,
937-
"test",
938-
new HierarchyCircuitBreakerService.MemoryUsage(-2L, -3L, -4L, -5L),
939-
-6L,
940-
true,
941-
Map.of("child1", new TestChildCircuitBreaker(-7L))
942-
),
943-
equalTo(
944-
"[parent] Data too large, data for [test] would be [-3], which is larger than the limit of [-6], "
945-
+ "real usage: [-2], new bytes reserved: [-1], usages [child1=-7]"
946-
)
947-
);
948-
} finally {
949-
HierarchyCircuitBreakerService.permitNegativeValues = false;
950-
}
951-
}
952876
}

0 commit comments

Comments
 (0)