Skip to content

Commit 76e7bd0

Browse files
committed
Revert "Make CBE message creation more robust (#87876)"
This reverts commit 62650ef.
1 parent 62650ef commit 76e7bd0

5 files changed

Lines changed: 54 additions & 237 deletions

File tree

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 StringBuilder 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: 35 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.util.Map;
3838
import java.util.concurrent.atomic.AtomicLong;
3939
import java.util.concurrent.locks.ReentrantLock;
40-
import java.util.function.BiConsumer;
4140
import java.util.function.Function;
4241
import java.util.function.LongSupplier;
4342
import java.util.stream.Collectors;
@@ -418,78 +417,47 @@ public void checkParentLimit(long newBytesReserved, String label) throws Circuit
418417
long parentLimit = this.parentSettings.getLimit();
419418
if (memoryUsed.totalUsage > parentLimit && overLimitStrategy.overLimit(memoryUsed).totalUsage > parentLimit) {
420419
this.parentTripCount.incrementAndGet();
421-
final String messageString = buildParentTripMessage(
422-
newBytesReserved,
423-
label,
424-
memoryUsed,
425-
parentLimit,
426-
this.trackRealMemoryUsage,
427-
this.breakers
420+
final StringBuilder message = new StringBuilder(
421+
"[parent] Data too large, data for ["
422+
+ label
423+
+ "]"
424+
+ " would be ["
425+
+ memoryUsed.totalUsage
426+
+ "/"
427+
+ new ByteSizeValue(memoryUsed.totalUsage)
428+
+ "]"
429+
+ ", which is larger than the limit of ["
430+
+ parentLimit
431+
+ "/"
432+
+ new ByteSizeValue(parentLimit)
433+
+ "]"
428434
);
435+
if (this.trackRealMemoryUsage) {
436+
final long realUsage = memoryUsed.baseUsage;
437+
message.append(", real usage: [");
438+
message.append(realUsage);
439+
message.append("/");
440+
message.append(new ByteSizeValue(realUsage));
441+
message.append("], new bytes reserved: [");
442+
message.append(newBytesReserved);
443+
message.append("/");
444+
message.append(new ByteSizeValue(newBytesReserved));
445+
message.append("]");
446+
}
447+
message.append(", usages [");
448+
message.append(this.breakers.entrySet().stream().map(e -> {
449+
final CircuitBreaker breaker = e.getValue();
450+
final long breakerUsed = (long) (breaker.getUsed() * breaker.getOverhead());
451+
return e.getKey() + "=" + breakerUsed + "/" + new ByteSizeValue(breakerUsed);
452+
}).collect(Collectors.joining(", ")));
453+
message.append("]");
429454
// derive durability of a tripped parent breaker depending on whether the majority of memory tracked by
430455
// child circuit breakers is categorized as transient or permanent.
431456
CircuitBreaker.Durability durability = memoryUsed.transientChildUsage >= memoryUsed.permanentChildUsage
432457
? CircuitBreaker.Durability.TRANSIENT
433458
: CircuitBreaker.Durability.PERMANENT;
434-
logger.debug(() -> new ParameterizedMessage("{}", messageString));
435-
throw new CircuitBreakingException(messageString, memoryUsed.totalUsage, parentLimit, durability);
436-
}
437-
}
438-
439-
// exposed for tests
440-
static String buildParentTripMessage(
441-
long newBytesReserved,
442-
String label,
443-
MemoryUsage memoryUsed,
444-
long parentLimit,
445-
boolean trackRealMemoryUsage,
446-
Map<String, CircuitBreaker> breakers
447-
) {
448-
final StringBuilder message = new StringBuilder();
449-
message.append("[parent] Data too large, data for [");
450-
message.append(label);
451-
message.append("] would be [");
452-
appendBytesSafe(message, memoryUsed.totalUsage);
453-
message.append("], which is larger than the limit of [");
454-
appendBytesSafe(message, parentLimit);
455-
message.append("]");
456-
if (trackRealMemoryUsage) {
457-
final long realUsage = memoryUsed.baseUsage;
458-
message.append(", real usage: [");
459-
appendBytesSafe(message, realUsage);
460-
message.append("], new bytes reserved: [");
461-
appendBytesSafe(message, newBytesReserved);
462-
message.append("]");
463-
}
464-
message.append(", usages [");
465-
breakers.forEach(new BiConsumer<String, CircuitBreaker>() {
466-
private boolean first = true;
467-
468-
@Override
469-
public void accept(String key, CircuitBreaker breaker) {
470-
if (first) {
471-
first = false;
472-
} else {
473-
message.append(", ");
474-
}
475-
message.append(key).append("=");
476-
appendBytesSafe(message, (long) (breaker.getUsed() * breaker.getOverhead()));
477-
}
478-
});
479-
message.append("]");
480-
return message.toString();
481-
}
482-
483-
static void appendBytesSafe(StringBuilder stringBuilder, long bytes) {
484-
stringBuilder.append(bytes);
485-
if (bytes >= 0) {
486-
stringBuilder.append("/");
487-
stringBuilder.append(new ByteSizeValue(bytes));
488-
} else {
489-
// Something's definitely wrong, maybe a breaker was freed twice? Still, we're just creating an exception message here, so we
490-
// should keep going if we're running in production.
491-
logger.error("negative value in circuit breaker: {}", stringBuilder);
492-
assert permitNegativeValues : stringBuilder.toString();
459+
logger.debug(() -> new ParameterizedMessage("{}", message.toString()));
460+
throw new CircuitBreakingException(message.toString(), memoryUsed.totalUsage, parentLimit, durability);
493461
}
494462
}
495463

@@ -688,7 +656,4 @@ TimeValue getLockTimeout() {
688656
return lockTimeout;
689657
}
690658
}
691-
692-
// exposed for testing
693-
static boolean permitNegativeValues = false;
694659
}

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

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

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

Lines changed: 0 additions & 75 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;
@@ -47,7 +46,6 @@
4746
import static org.hamcrest.Matchers.lessThanOrEqualTo;
4847
import static org.hamcrest.Matchers.not;
4948
import static org.hamcrest.Matchers.nullValue;
50-
import static org.hamcrest.Matchers.oneOf;
5149
import static org.hamcrest.Matchers.sameInstance;
5250

5351
public class HierarchyCircuitBreakerServiceTests extends ESTestCase {
@@ -819,77 +817,4 @@ public void testCustomCircuitBreakers() {
819817
private static long mb(long size) {
820818
return new ByteSizeValue(size, ByteSizeUnit.MB).getBytes();
821819
}
822-
823-
public void testBuildParentTripMessage() {
824-
class TestChildCircuitBreaker extends NoopCircuitBreaker {
825-
private final long used;
826-
827-
TestChildCircuitBreaker(long used) {
828-
super("child");
829-
this.used = used;
830-
}
831-
832-
@Override
833-
public long getUsed() {
834-
return used;
835-
}
836-
837-
@Override
838-
public double getOverhead() {
839-
return 1.0;
840-
}
841-
}
842-
843-
assertThat(
844-
HierarchyCircuitBreakerService.buildParentTripMessage(
845-
1L,
846-
"test",
847-
new HierarchyCircuitBreakerService.MemoryUsage(2L, 3L, 4L, 5L),
848-
6L,
849-
false,
850-
org.elasticsearch.core.Map.of("child", new TestChildCircuitBreaker(7L), "otherChild", new TestChildCircuitBreaker(8L))
851-
),
852-
oneOf(
853-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
854-
+ "usages [child=7/7b, otherChild=8/8b]",
855-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
856-
+ "usages [otherChild=8/8b, child=7/7b]"
857-
)
858-
);
859-
860-
assertThat(
861-
HierarchyCircuitBreakerService.buildParentTripMessage(
862-
1L,
863-
"test",
864-
new HierarchyCircuitBreakerService.MemoryUsage(2L, 3L, 4L, 5L),
865-
6L,
866-
true,
867-
org.elasticsearch.core.Map.of()
868-
),
869-
equalTo(
870-
"[parent] Data too large, data for [test] would be [3/3b], which is larger than the limit of [6/6b], "
871-
+ "real usage: [2/2b], new bytes reserved: [1/1b], usages []"
872-
)
873-
);
874-
875-
try {
876-
HierarchyCircuitBreakerService.permitNegativeValues = true;
877-
assertThat(
878-
HierarchyCircuitBreakerService.buildParentTripMessage(
879-
-1L,
880-
"test",
881-
new HierarchyCircuitBreakerService.MemoryUsage(-2L, -3L, -4L, -5L),
882-
-6L,
883-
true,
884-
org.elasticsearch.core.Map.of("child1", new TestChildCircuitBreaker(-7L))
885-
),
886-
equalTo(
887-
"[parent] Data too large, data for [test] would be [-3], which is larger than the limit of [-6], "
888-
+ "real usage: [-2], new bytes reserved: [-1], usages [child1=-7]"
889-
)
890-
);
891-
} finally {
892-
HierarchyCircuitBreakerService.permitNegativeValues = false;
893-
}
894-
}
895820
}

0 commit comments

Comments
 (0)