From 3dd53bad89181f385570e762d6b54dcfb949ced9 Mon Sep 17 00:00:00 2001 From: jerryjzhang Date: Mon, 22 Sep 2025 15:59:35 +0800 Subject: [PATCH] (fix)(headless)Fix concurrent modification exception issue. --- .../headless/chat/knowledge/MultiCustomDictionary.java | 8 +++++--- .../supersonic/headless/chat/knowledge/SearchService.java | 3 ++- .../supersonic/headless/chat/parser/llm/PromptHelper.java | 3 ++- .../headless/core/translator/parser/SqlQueryParser.java | 3 ++- .../server/service/impl/DimensionServiceImpl.java | 8 +++----- .../headless/server/service/impl/MetricServiceImpl.java | 6 ++---- .../headless/server/utils/DataSetSchemaBuilder.java | 8 +++++--- 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/MultiCustomDictionary.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/MultiCustomDictionary.java index 79cefa92f..c6ba9ec5c 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/MultiCustomDictionary.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/MultiCustomDictionary.java @@ -33,6 +33,7 @@ import java.util.Objects; import java.util.PriorityQueue; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.PriorityBlockingQueue; import static com.hankcs.hanlp.utility.Predefine.logger; @@ -40,7 +41,7 @@ public class MultiCustomDictionary extends DynamicCustomDictionary { public static int MAX_SIZE = 10; public static Boolean removeDuplicates = true; - public static ConcurrentHashMap> NATURE_TO_VALUES = + public static ConcurrentHashMap> NATURE_TO_VALUES = new ConcurrentHashMap<>(); private static boolean addToSuggesterTrie = true; @@ -146,9 +147,10 @@ public class MultiCustomDictionary extends DynamicCustomDictionary { } for (int i = 0; i < attribute.nature.length; i++) { Nature nature = attribute.nature[i]; - PriorityQueue priorityQueue = NATURE_TO_VALUES.get(nature.toString()); + PriorityBlockingQueue priorityQueue = + NATURE_TO_VALUES.get(nature.toString()); if (Objects.isNull(priorityQueue)) { - priorityQueue = new PriorityQueue<>(MAX_SIZE, + priorityQueue = new PriorityBlockingQueue<>(MAX_SIZE, Comparator.comparingInt(Term::getFrequency).reversed()); NATURE_TO_VALUES.put(nature.toString(), priorityQueue); } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/SearchService.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/SearchService.java index 40a9504b2..8c14ffa53 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/SearchService.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/knowledge/SearchService.java @@ -24,6 +24,7 @@ import java.util.PriorityQueue; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; +import java.util.concurrent.PriorityBlockingQueue; import java.util.stream.Collectors; @Slf4j @@ -200,7 +201,7 @@ public class SearchService { public static List getDimensionValue(DimensionValueReq dimensionValueReq) { String nature = DictWordType.NATURE_SPILT + dimensionValueReq.getModelId() + DictWordType.NATURE_SPILT + dimensionValueReq.getElementID(); - PriorityQueue terms = MultiCustomDictionary.NATURE_TO_VALUES.get(nature); + PriorityBlockingQueue terms = MultiCustomDictionary.NATURE_TO_VALUES.get(nature); if (CollectionUtils.isEmpty(terms)) { return new ArrayList<>(); } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/PromptHelper.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/PromptHelper.java index 3ce5f4b80..8513d650e 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/PromptHelper.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/PromptHelper.java @@ -144,7 +144,8 @@ public class PromptHelper { dimensionStr.append(" ALIAS '").append(alias).append("'"); } if (Objects.nonNull(dimension.getExtInfo().get(DIMENSION_DATA_TYPE))) { - dimensionStr.append(" DATATYPE '").append(dimension.getExtInfo().get(DIMENSION_DATA_TYPE)).append("'"); + dimensionStr.append(" DATATYPE '") + .append(dimension.getExtInfo().get(DIMENSION_DATA_TYPE)).append("'"); } if (StringUtils.isNotEmpty(dimension.getTimeFormat())) { dimensionStr.append(" FORMAT '").append(dimension.getTimeFormat()).append("'"); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java index 675ff84f6..b6a7206ce 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/SqlQueryParser.java @@ -47,7 +47,8 @@ public class SqlQueryParser implements QueryParser { SqlQuery sqlQuery = queryStatement.getSqlQuery(); List queryFields = SqlSelectHelper.getAllSelectFields(sqlQuery.getSql()); Set queryAliases = SqlSelectHelper.getAliasFields(sqlQuery.getSql()); - List> ontologyMetricsDimensionsAndBizName = Collections.synchronizedList(new ArrayList<>()); + List> ontologyMetricsDimensionsAndBizName = + Collections.synchronizedList(new ArrayList<>()); queryFields.removeAll(queryAliases); Ontology ontology = queryStatement.getOntology(); OntologyQuery ontologyQuery = buildOntologyQuery(ontology, queryFields); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DimensionServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DimensionServiceImpl.java index 7f97af235..14edb7b68 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DimensionServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DimensionServiceImpl.java @@ -519,7 +519,7 @@ public class DimensionServiceImpl extends ServiceImpl dimensionDOS, EventType eventType) { - List dataItems = - dimensionDOS.stream().map(this::getDataItem) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + List dataItems = dimensionDOS.stream().map(this::getDataItem) + .filter(Objects::nonNull).collect(Collectors.toList()); return new DataEvent(this, dataItems, eventType); } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/MetricServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/MetricServiceImpl.java index 823849fb6..51f06c83b 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/MetricServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/MetricServiceImpl.java @@ -682,10 +682,8 @@ public class MetricServiceImpl extends ServiceImpl } private DataEvent getDataEvent(List metricDOS, EventType eventType) { - List dataItems = - metricDOS.stream().map(this::getDataItem) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + List dataItems = metricDOS.stream().map(this::getDataItem) + .filter(Objects::nonNull).collect(Collectors.toList()); return new DataEvent(this, dataItems, eventType); } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DataSetSchemaBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DataSetSchemaBuilder.java index 6bf4b975c..952996424 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DataSetSchemaBuilder.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DataSetSchemaBuilder.java @@ -96,8 +96,9 @@ public class DataSetSchemaBuilder { Set dimensions = new HashSet<>(); Map> dataTypeMap = Maps.newHashMap(); for (ModelResp modelResp : resp.getModelResps()) { - dataTypeMap.put(modelResp.getId(), modelResp.getModelDetail().getFields().stream() - .collect(Collectors.toMap(Field::getFieldName, Field::getDataType, (k1, k2) -> k2))); + dataTypeMap.put(modelResp.getId(), + modelResp.getModelDetail().getFields().stream().collect(Collectors + .toMap(Field::getFieldName, Field::getDataType, (k1, k2) -> k2))); } for (DimSchemaResp dim : resp.getDimensions()) { @@ -119,7 +120,8 @@ public class DataSetSchemaBuilder { dimToAdd.getExtInfo().put(DimensionConstants.DIMENSION_TYPE, dim.getType()); // data type if (dim.getDataType() != null) { - dimToAdd.getExtInfo().put(DimensionConstants.DIMENSION_DATA_TYPE, dim.getDataType()); + dimToAdd.getExtInfo().put(DimensionConstants.DIMENSION_DATA_TYPE, + dim.getDataType()); } else { dimToAdd.getExtInfo().put(DimensionConstants.DIMENSION_DATA_TYPE, dataTypeMap.get(dim.getModelId()).get(dim.getBizName()));