Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import modelengine.fit.jober.aipp.constants.AippConst;
import modelengine.fit.jober.aipp.domain.AppBuilderRuntimeInfo;
import modelengine.fit.jober.aipp.dto.chat.AppChatRsp;
import modelengine.fit.jober.aipp.entity.ChatSession;
import modelengine.fit.jober.aipp.repository.AppBuilderRuntimeInfoRepository;
import modelengine.fit.jober.aipp.service.AppChatSessionService;
import modelengine.fit.jober.aipp.service.AppChatSseService;
Expand Down Expand Up @@ -88,13 +89,17 @@ public void publishNodeInfo(FlowNodePublishInfo flowNodePublishInfo) {

private void stageProcessedHandle(FlowNodePublishInfo flowNodePublishInfo, Map<String, Object> businessData,
String aippInstId) {
Optional<ChatSession<Object>> instanceSession = this.appChatSessionService.getSession(aippInstId);
if (instanceSession.isPresent() && !instanceSession.get().isDebug()) {
return;
}
FlowPublishContext context = flowNodePublishInfo.getFlowContext();
String traceId = context.getTraceId();
String nodeId = flowNodePublishInfo.getNodeId();
String nodeType = flowNodePublishInfo.getNodeType();
FlowErrorInfo errorInfo = flowNodePublishInfo.getErrorMsg();
AtomicReference<Locale> locale = new AtomicReference<>(Locale.getDefault());
appChatSessionService.getSession(aippInstId).ifPresent(e -> locale.set(e.getLocale()));
instanceSession.ifPresent(session -> locale.set(session.getLocale()));
ToolExceptionHandle.handleFitException(errorInfo);
String finalErrorMsg = this.toolExceptionHandle.getFixErrorMsg(errorInfo, locale.get(), false);
if (StringUtils.isBlank(finalErrorMsg)) {
Expand All @@ -103,7 +108,7 @@ private void stageProcessedHandle(FlowNodePublishInfo flowNodePublishInfo, Map<S
AppBuilderRuntimeInfo runtimeInfo = AppBuilderRuntimeInfo.builder()
.traceId(traceId)
.flowDefinitionId(flowNodePublishInfo.getFlowDefinitionId())
.instanceId(ObjectUtils.cast(businessData.get(AippConst.BS_AIPP_INST_ID_KEY)))
.instanceId(aippInstId)
.nodeId(nodeId)
.nodeType(nodeType)
.startTime(ConvertUtils.toLong(context.getCreateAt()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public String createAippInstance(String aippId, String version, Map<String, Obje
@Fitable("default")
public String createLatestAippInstanceByAppId(String appId, boolean isDebug, Map<String, Object> initContext,
OperationContext context) {
Meta meta = getMetaByAppId(metaService, appId, isDebug, context);
Meta meta = CacheUtils.getMetaByAppId(metaService, appId, isDebug, context);
String metaInstId = this.createAippInstance(meta.getId(), meta.getVersion(), initContext, context);
return metaInstanceService.list(Collections.singletonList(metaInstId), 0, 1, context)
.getResults()
Expand All @@ -268,46 +268,16 @@ public String createLatestAippInstanceByAppId(String appId, boolean isDebug, Map
@Override
public Tuple createInstanceByApp(String appId, String question, Map<String, Object> businessData,
OperationContext context, boolean isDebug) {
Meta meta = getMetaByAppId(metaService, appId, isDebug, context);
Meta meta = CacheUtils.getMetaByAppId(metaService, appId, isDebug, context);
return this.createInstanceHandle(question, businessData, meta, context, isDebug);
}

@Override
public MetaVo queryLatestMetaVoByAppId(String appId, boolean isDebug, OperationContext context) {
Meta meta = getMetaByAppId(metaService, appId, isDebug, context);
Meta meta = CacheUtils.getMetaByAppId(metaService, appId, isDebug, context);
return MetaVo.builder().id(meta.getId()).version(meta.getVersion()).build();
}

/**
* 根据appid查询对应meta
*
* @param metaService 操作meta的service
* @param appId 应用appId
* @param isDebug 是否为debug会话
* @param context 操作上下文
* @return app对应的meta信息
*/
public static Meta getMetaByAppId(MetaService metaService, String appId, boolean isDebug,
OperationContext context) {
if (isDebug) {
return getLatestMetaByAppId(metaService, appId, context);
}
// get 一个aipp_id的缓存,然后根据aipp_id查询最新发布版的meta
String aippId = CacheUtils.APP_ID_TO_AIPP_ID_CACHE.get(appId,
(id) -> getLatestMetaByAppId(metaService, id, context).getId());
Meta lastPublishedMeta = MetaUtils.getLastPublishedMeta(metaService, aippId, context);
return Optional.ofNullable(lastPublishedMeta)
.orElseThrow(() -> new AippException(AippErrCode.APP_CHAT_PUBLISHED_META_NOT_FOUND));
}

private static Meta getLatestMetaByAppId(MetaService metaService, String appId, OperationContext context) {
List<Meta> meta = MetaUtils.getAllMetasByAppId(metaService, appId, context);
if (CollectionUtils.isEmpty(meta)) {
throw new AippException(AippErrCode.APP_CHAT_DEBUG_META_NOT_FOUND);
}
return meta.get(0);
}

@Override
public Choir<Object> startFlowWithUserSelectMemory(String metaInstId, Map<String, Object> initContext,
OperationContext context, boolean isDebug) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import static modelengine.fit.jober.aipp.constants.AippConst.BUSINESS_INFOS_KEY;
import static modelengine.fit.jober.aipp.constants.AippConst.BUSINESS_INPUT_KEY;
import static modelengine.fit.jober.aipp.enums.AppTypeEnum.APP;
import static modelengine.fit.jober.aipp.service.impl.AippRunTimeServiceImpl.getMetaByAppId;

import modelengine.fit.jade.waterflow.FlowsService;
import modelengine.fit.jane.common.entity.OperationContext;
Expand Down Expand Up @@ -43,9 +42,9 @@
import modelengine.fit.jober.aipp.service.AppChatService;
import modelengine.fit.jober.aipp.util.AippLogUtils;
import modelengine.fit.jober.aipp.util.AppUtils;
import modelengine.fit.jober.aipp.util.CacheUtils;
import modelengine.fit.jober.aipp.util.FlowUtils;
import modelengine.fit.jober.aipp.util.JsonUtils;
import modelengine.fit.jober.aipp.util.MetaUtils;
import modelengine.fit.jober.aipp.util.UUIDUtil;
import modelengine.fit.jober.common.ServerInternalException;
import modelengine.fitframework.annotation.Component;
Expand Down Expand Up @@ -132,11 +131,13 @@ public Choir<Object> chat(CreateAppChatRequest body, OperationContext context, b
Map<String, Object> businessData = this.convertContextToBusinessData(body, isDebug);
// 这里几行代码的顺序不可以调整,必须先把对话的appId查询出来,再去创建chatId
String chatAppId = this.getAppId(body);
boolean hasAtOtherApp = this.hasAtOtherApp(body);
boolean hasAtOtherApp = body.hasAtOtherApp();
this.createChatId(body, hasAtOtherApp, businessData);
// create instance —— 根据实际的那个app创建
AppUtils.setAppChatInfo(body.getAppId(), isDebug);
this.appService.updateFlow(chatAppId, context);
if (isDebug) {
this.appService.updateFlow(chatAppId, context);
}
LOGGER.info("[perf] [{}] chat updateFlow end, appId={}", System.currentTimeMillis(), body.getAppId());
this.addUserContext(body, businessData, isDebug, context, app.getType());
Tuple tuple = this.aippRunTimeService.createInstanceByApp(chatAppId,
Expand All @@ -150,8 +151,8 @@ public Choir<Object> chat(CreateAppChatRequest body, OperationContext context, b
this.saveChatInfos(body,
context,
ObjectUtils.cast(tuple.get(0).orElseThrow(this::generalServerException)),
hasAtOtherApp,
chatAppId);
chatAppId,
isDebug);
} catch (AippTaskNotFoundException e) {
throw new AippException(TASK_NOT_FOUND);
}
Expand Down Expand Up @@ -243,15 +244,15 @@ private void validateApp(String appId) {
}

private void saveChatInfos(CreateAppChatRequest body, OperationContext context, String instId,
boolean hasAtOtherApp, String chatAppId) throws AippTaskNotFoundException {
String chatAppId, boolean isDebug) throws AippTaskNotFoundException {
AppBuilderApp app = this.appFactory.create(body.getAppId());
Map<String, String> attributes = new HashMap<>();
List<Meta> metas = MetaUtils.getAllMetasByAppId(this.metaService, chatAppId, context);
if (CollectionUtils.isEmpty(metas)) {
LOGGER.error("metas is empty.");
Meta meta = CacheUtils.getMetaByAppId(this.metaService, chatAppId, isDebug, context);
if (meta == null) {
LOGGER.error("Cannot find meta for chat app. [appId={}, instId={}]", chatAppId, instId);
throw new AippTaskNotFoundException(TASK_NOT_FOUND);
}
String aippId = metas.get(0).getId();
String aippId = meta.getId();
attributes.put(AippConst.ATTR_CHAT_INST_ID_KEY, instId);
attributes.put(AippConst.ATTR_CHAT_STATE_KEY, app.getState());
attributes.put(AippConst.BS_AIPP_ID_KEY, aippId);
Expand All @@ -261,7 +262,7 @@ private void saveChatInfos(CreateAppChatRequest body, OperationContext context,
String chatId = body.getChatId();
this.buildAndInsertChatInfo(app, attributes, body.getQuestion(), chatId, context.getOperator());
this.buildAndInsertWideRelationInfo(instId, chatId);
if (hasAtOtherApp) {
if (body.hasAtOtherApp()) {
AppBuilderApp chatApp = this.appFactory.create(chatAppId);
// 被@的应用的对话
Map<String, String> originAttributes = new HashMap<>();
Expand All @@ -287,9 +288,9 @@ private Map<String, Object> convertContextToBusinessData(CreateAppChatRequest bo

private void addUserContext(CreateAppChatRequest body, Map<String, Object> businessData, boolean isDebug,
OperationContext context, String appType) {
Meta meta = getMetaByAppId(metaService, body.getAppId(), isDebug, context);
Meta meta = CacheUtils.getMetaByAppId(this.metaService, body.getAppId(), isDebug, context);
String flowDefinitionId = ObjectUtils.cast(meta.getAttributes().get(ATTR_FLOW_DEF_ID_KEY));
List<AppInputParam> inputParams = FlowUtils.getAppInputParams(flowsService, flowDefinitionId, context);
List<AppInputParam> inputParams = FlowUtils.getAppInputParams(this.flowsService, flowDefinitionId, context);
if (StringUtils.equals(APP.code(), appType)) {
inputParams = inputParams.stream()
.filter(param -> !StringUtils.equals("Question", param.getName()))
Expand Down Expand Up @@ -376,11 +377,6 @@ private String getAppId(CreateAppChatRequest body) {
return body.getAppId();
}

private boolean hasAtOtherApp(CreateAppChatRequest body) {
return StringUtils.isNotBlank(body.getContext().getAtChatId()) || StringUtils.isNotBlank(body.getContext()
.getAtAppId());
}

private void createChatId(CreateAppChatRequest body, boolean hasAtOtherApp, Map<String, Object> businessData) {
// body里没有chatId:第一次对话
if (StringUtils.isBlank(body.getChatId())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
import modelengine.fit.jade.waterflow.FlowsService;
import modelengine.fit.jade.waterflow.dto.FlowInfo;
import modelengine.fit.jane.common.entity.OperationContext;
import modelengine.fit.jane.meta.multiversion.MetaService;
import modelengine.fit.jane.meta.multiversion.definition.Meta;
import modelengine.fit.jober.aipp.common.exception.AippErrCode;
import modelengine.fit.jober.aipp.common.exception.AippException;
import modelengine.fit.jober.aipp.po.AppBuilderAppPo;
import modelengine.fitframework.annotation.Component;
import modelengine.fitframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -50,29 +57,70 @@ public class CacheUtils {
.maximumSize(1000)
.build();

/**
* 用于缓存app_id和meta的关系
*/
public static final Cache<String, Meta> AIPP_ID_LAST_META_CACHE = Caffeine.newBuilder()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
  1. 该缓存命名不明确,其中 LAST 是什么意思?
  2. 该缓存是不是应该把访问权限收归到 private,然后仅通过方法来访问?而不是公开了之后支持任意访问
  3. 该缓存的注释需要调整,详细说清楚到底缓存了什么内容。

.expireAfterAccess(5, TimeUnit.SECONDS)
.maximumSize(1000)
.build();

/**
* 清理缓存
*/
public static void clear() {
APP_CACHE.invalidateAll();
FLOW_CACHE.invalidateAll();
APP_ID_TO_AIPP_ID_CACHE.invalidateAll();
AIPP_ID_LAST_META_CACHE.invalidateAll();

APP_CACHE.cleanUp();
FLOW_CACHE.cleanUp();
APP_ID_TO_AIPP_ID_CACHE.cleanUp();
AIPP_ID_LAST_META_CACHE.cleanUp();
}

/**
* 用于获取flowdefinition的缓存
*
* @param flowsService 操作flow的service
* @param flowsService 操作flow的service
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

注释风格需要全团队统一,采用代码仓库提供的格式化文件,不需要参数注释对齐,同时注释需要采用统一风格。这里可以改成如下:

/**
     * 通过缓存获取指定的已发布流程。
     *
     * @param flowsService 表示流程服务的 {@link FlowsService}。
     * @param flowDefinitionId 表示流程定义的唯一标识的 {@link String}。
     * @param context 表示操作上下文的 {@link OperationContext}。
     * @return 表示缓存流程信息的 {@link FlowInfo}。
     */

* @param flowDefinitionId 缓存的flowDefinition的id
* @param context 人员上下文
* @param context 人员上下文
* @return 缓存的FlowInfo
*/
public static FlowInfo getPublishedFlowWithCache(FlowsService flowsService, String flowDefinitionId,
OperationContext context) {
return FLOW_CACHE.get(flowDefinitionId, id -> flowsService.getFlows(id, context));
}

/**
* 根据appId查询对应meta
*
* @param metaService 用于查询meta的服务实例
* @param appId 应用appId
* @param isDebug 是否为debug会话
* @param context 操作上下文
* @return app对应的meta信息
*/
public static Meta getMetaByAppId(MetaService metaService, String appId, boolean isDebug,
OperationContext context) {
if (isDebug) {
return getLatestMetaByAppId(metaService, appId, context);
}
// get一个aipp_id的缓存,然后根据aipp_id查询最新发布版的meta
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

如果要进行行内注释,需要写清楚,尽量不要中英文混杂,同时,团队统一规范,最后加上全角句号

String aippId = APP_ID_TO_AIPP_ID_CACHE.get(appId, id -> getLatestMetaByAppId(metaService, id, context).getId());
return AIPP_ID_LAST_META_CACHE.get(aippId, (ignore) -> {
Meta lastPublishedMeta = MetaUtils.getLastPublishedMeta(metaService, appId, context);
return Optional.ofNullable(lastPublishedMeta)
.orElseThrow(() -> new AippException(AippErrCode.APP_CHAT_PUBLISHED_META_NOT_FOUND));
});
}

private static Meta getLatestMetaByAppId(MetaService metaService, String appId, OperationContext context) {
List<Meta> metas = MetaUtils.getAllMetasByAppId(metaService, appId, context);
if (CollectionUtils.isEmpty(metas)) {
throw new AippException(AippErrCode.APP_CHAT_DEBUG_META_NOT_FOUND);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

这里抛出异常的时候无日志,也没有将必要的参数信息透出,会对定位问题造成困扰。

}
return metas.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import lombok.NoArgsConstructor;
import modelengine.fit.jober.aipp.constants.AippConst;
import modelengine.fitframework.annotation.Property;
import modelengine.fitframework.util.StringUtils;

import java.util.Map;

Expand All @@ -38,6 +39,15 @@ public class CreateAppChatRequest {
@Property(description = "context", name = "context")
private Context context;

/**
* 判断是否有@应用
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

注释风格统一,且需要写明确,不要存在简写

*
* @return true-有; false-没有
*/
public boolean hasAtOtherApp() {
return StringUtils.isNotBlank(getContext().getAtChatId()) || StringUtils.isNotBlank(getContext().getAtAppId());
}

/**
* 本类表示对话的上下文
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.fit.waterflow.common.utils;

import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

/**
* Uuid的Utils类。
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

注释调整,同时 @since 后面需要跟创建该文件的时间,格式为 yyyy-MM-dd

*
* @author 孙怡菲
* @since 1.0
*/
public class UUIDUtil {
/**
* 随机生成uuid。
*
* @return 随机生成的uuid的 {@link String}。
*/
public static String uuid() {
return UUID.randomUUID().toString().replace("-", "");
}

/**
* 使用线程本地随机数生成UUID。
* 生成的 UUID 在唯一性和不可预测性上可能不如 UUID.randomUUID(),但在性能上有显著提升
*
* @return 生成的UUID。
*/
public static String fastUuid() {
long mostSigBits = ThreadLocalRandom.current().nextLong();
long leastSigBits = ThreadLocalRandom.current().nextLong();

// 设置版本4和变体IETF
mostSigBits &= 0xffffffffffff0fffL;
mostSigBits |= 0x0000000000004000L;
leastSigBits &= 0x3fffffffffffffffL;
leastSigBits |= 0x8000000000000000L;

return new UUID(mostSigBits, leastSigBits).toString().replace("-", "");
}
}
Loading