Skip to content

Commit 4b69224

Browse files
author
gitlab
committed
Merge branch 'fix/ZSTAC-72079-similarity-perf' into '5.5.12'
<fix>[utils]: fix StringSimilarity concurrency, distance filter, slow log (ZSTAC-72079) See merge request zstackio/zstack!9269
2 parents 0765359 + eaffb32 commit 4b69224

4 files changed

Lines changed: 39 additions & 10 deletions

File tree

core/src/main/java/org/zstack/core/CoreGlobalProperty.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class CoreGlobalProperty {
1212
@GlobalProperty(name = "unitTestOn", defaultValue = "false")
1313
@AvailableValues(value ={"true","false"})
1414
public static boolean UNIT_TEST_ON;
15+
@GlobalProperty(name = "elaboration.slowThresholdMs", defaultValue = "0")
16+
public static long ELABORATION_SLOW_THRESHOLD_MS;
1517
@GlobalProperty(name = "beanRefContextConf", defaultValue = "beanRefContext.xml")
1618
public static String BEAN_REF_CONTEXT_CONF;
1719
@GlobalProperty(name = "beanConf", defaultValue = "zstack.xml")

core/src/main/java/org/zstack/core/Platform.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,14 @@ public static boolean killProcess(int pid, Integer timeout) {
936936
}
937937
}
938938

939+
private static volatile boolean slowElaborationWired = false;
940+
939941
private static ErrorCodeElaboration elaborate(String fmt, Object...args) {
942+
if (!slowElaborationWired) {
943+
StringSimilarity.slowElaborationThresholdMs = CoreGlobalProperty.ELABORATION_SLOW_THRESHOLD_MS;
944+
slowElaborationWired = true;
945+
}
946+
940947
try {
941948
ErrorCodeElaboration elaboration = StringSimilarity.findSimilar(fmt, args);
942949
if (elaboration == null) {

test/src/test/resources/zstack.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Zdfs.agentPort=8989
4545
ApiMediator.apiWorkerNum=50
4646

4747
unitTestOn=true
48+
elaboration.slowThresholdMs=200
4849
exitJVMOnStop=false
4950

5051
#CloudBus.closeTracker=true

utils/src/main/java/org/zstack/utils/string/StringSimilarity.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public class StringSimilarity {
3232

3333
private static final int mapLength = 1500;
3434
public static int maxElaborationRegex = 8192;
35+
// slow elaboration warn threshold in ms; 0 = disabled (default)
36+
// enable via GlobalProperty or test setup: StringSimilarity.slowElaborationThresholdMs = 200;
37+
public static long slowElaborationThresholdMs = 0;
3538

3639
// matched errors
3740
private static final Map<String, ErrorCodeElaboration> errors = new LinkedHashMap<String, ErrorCodeElaboration>(mapLength, 0.9f, true) {
@@ -280,8 +283,15 @@ private static boolean isRedundant(String sub) {
280283
}
281284

282285
private static void logSearchSpend(String sub, long start, boolean found) {
283-
logger.debug(String.format("[%s] spend %s ms to search elaboration \"%s\"", found, System.currentTimeMillis() - start,
284-
sub.length() > 50 ? sub.substring(0 , 50) + "..." : sub));
286+
long cost = System.currentTimeMillis() - start;
287+
if (slowElaborationThresholdMs > 0 && cost > slowElaborationThresholdMs) {
288+
logger.warn(String.format("[SLOW-ELABORATION] cost %d ms, found=%s, input_len=%d, input=%s",
289+
cost, found, sub.length(),
290+
sub.length() > 100 ? sub.substring(0, 100) + "..." : sub));
291+
} else {
292+
logger.debug(String.format("[%s] spend %s ms to search elaboration \"%s\"", found, cost,
293+
sub.length() > 50 ? sub.substring(0, 50) + "..." : sub));
294+
}
285295
}
286296

287297
/**
@@ -306,7 +316,10 @@ public static ErrorCodeElaboration findSimilar(String sub, Object...args) {
306316
}
307317

308318
long start = System.currentTimeMillis();
309-
ErrorCodeElaboration err = errors.get(sub);
319+
ErrorCodeElaboration err;
320+
synchronized (errors) {
321+
err = errors.get(sub);
322+
}
310323
if (err != null && verifyElaboration(err, sub, args)) {
311324
logSearchSpend(sub, start, true);
312325
return err;
@@ -317,20 +330,26 @@ public static ErrorCodeElaboration findSimilar(String sub, Object...args) {
317330
// same cause will happen
318331
// invalid cache, generate elaboration again
319332
if (err != null) {
320-
errors.remove(sub);
333+
synchronized (errors) {
334+
errors.remove(sub);
335+
}
321336
}
322337

323338
// check missed cache for both fmt template and formatted string
324-
if (missed.get(sub) != null) {
325-
logSearchSpend(sub, start, false);
326-
return null;
339+
synchronized (missed) {
340+
if (missed.get(sub) != null) {
341+
logSearchSpend(sub, start, false);
342+
return null;
343+
}
327344
}
328345
if (args != null) {
329346
try {
330347
String formatted = String.format(sub, args);
331-
if (missed.get(formatted) != null) {
332-
logSearchSpend(sub, start, false);
333-
return null;
348+
synchronized (missed) {
349+
if (missed.get(formatted) != null) {
350+
logSearchSpend(sub, start, false);
351+
return null;
352+
}
334353
}
335354
} catch (Exception e) {
336355
logger.trace(String.format("failed to format elaboration key: %s", e.getMessage()));

0 commit comments

Comments
 (0)