Skip to content

Commit e018af2

Browse files
committed
refactor(common): 替换线程本地会话上下文为CDI请求作用域
- 移除 SessionContextHolder 类及其 ThreadLocal 实现 - 引入新的 SessionContext 类,使用 @RequestScoped 注解 - 更新所有相关服务类以注入和使用新的 SessionContext - 在 AuthFilter 中替换 SessionContextHolder 的使用 - 在 AbstractRepository 中更新会话上下文访问方式 - 在 AuditDataEventListener 中切换到新的会话上下文 - 在 TriggerFlowEventConsumer 中使用新的会话上下文并添加清理逻辑 - 在 ProcessEngineImpl 中更新调用者和操作员设置 - 在 BranchService 和 ProjectService 中更新用户ID获取方式 - 在调度相关的服务和监听器中统一使用新的会话上下文 - 移除手动清理会话上下文的代码,依赖CDI自动管理生命周期
1 parent 5397641 commit e018af2

17 files changed

Lines changed: 147 additions & 152 deletions

‎flexmodel-server/src/main/java/dev/flexmodel/common/AbstractRepository.java‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ public abstract class AbstractRepository {
1515
@Inject
1616
protected SessionFactory sessionFactory;
1717

18+
@Inject
19+
protected SessionContext sessionContext;
20+
1821
protected Session getProjectSession(String projectId) {
1922
if (projectId != null) {
2023
// 仅当缓存的 projectId 与请求的一致时才复用 databaseName
21-
String cachedProjectId = SessionContextHolder.getProjectId();
24+
String cachedProjectId = sessionContext.getProjectId();
2225
if (projectId.equals(cachedProjectId)) {
23-
String cachedDb = SessionContextHolder.getProjectDatabaseName();
26+
String cachedDb = sessionContext.getProjectDatabaseName();
2427
if (cachedDb != null) {
2528
return sessionFactory.createSession(cachedDb);
2629
}
@@ -33,12 +36,12 @@ protected Session getProjectSession(String projectId) {
3336
if (project == null || project.getDatabaseName() == null) {
3437
throw new IllegalArgumentException("项目不存在或 databaseName 为空: " + projectId);
3538
}
36-
SessionContextHolder.setProjectId(projectId);
37-
SessionContextHolder.setProjectDatabaseName(project.getDatabaseName());
39+
sessionContext.setProjectId(projectId);
40+
sessionContext.setProjectDatabaseName(project.getDatabaseName());
3841
return sessionFactory.createSession(project.getDatabaseName());
3942
}
4043
}
41-
String projectDatabaseName = SessionContextHolder.getProjectDatabaseName();
44+
String projectDatabaseName = sessionContext.getProjectDatabaseName();
4245
if (projectDatabaseName != null) {
4346
return sessionFactory.createSession(projectDatabaseName);
4447
}

‎flexmodel-server/src/main/java/dev/flexmodel/common/AuditDataEventListener.java‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
package dev.flexmodel.common;
22

3-
import jakarta.enterprise.context.ApplicationScoped;
4-
import lombok.extern.slf4j.Slf4j;
53
import dev.flexmodel.event.EventListener;
64
import dev.flexmodel.event.PreChangeEvent;
75
import dev.flexmodel.event.impl.PreInsertEvent;
86
import dev.flexmodel.event.impl.PreUpdateEvent;
97
import dev.flexmodel.model.EntityDefinition;
108
import dev.flexmodel.model.field.TypedField;
11-
import dev.flexmodel.query.Query;
129
import dev.flexmodel.session.SessionFactory;
13-
import dev.flexmodel.JsonUtils;
10+
import jakarta.enterprise.context.ApplicationScoped;
11+
import jakarta.inject.Inject;
12+
import lombok.extern.slf4j.Slf4j;
1413

1514
import java.time.LocalDateTime;
16-
import java.util.ArrayList;
17-
import java.util.List;
1815
import java.util.Map;
1916

2017
/**
@@ -23,6 +20,10 @@
2320
@Slf4j
2421
@ApplicationScoped
2522
public class AuditDataEventListener implements EventListener {
23+
24+
@Inject
25+
SessionContext sessionContext;
26+
2627
@Override
2728
public void onPreChange(PreChangeEvent event) {
2829
if (!"system".equals(event.getSchemaName())) {
@@ -36,8 +37,8 @@ public void onPreChange(PreChangeEvent event) {
3637

3738
private void invokeData(PreChangeEvent event) {
3839
Map<String, Object> newData = event.getNewData();
39-
String projectId = SessionContextHolder.getProjectId();
40-
String userId = SessionContextHolder.getUserId();
40+
String projectId = sessionContext.getProjectId();
41+
String userId = sessionContext.getUserId();
4142
if (newData == null) {
4243
return;
4344
}

‎flexmodel-server/src/main/java/dev/flexmodel/common/SchemaRegistry.java‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
import jakarta.enterprise.context.ApplicationScoped;
1414
import jakarta.inject.Inject;
1515
import lombok.extern.slf4j.Slf4j;
16+
import org.eclipse.microprofile.config.ConfigProvider;
1617

1718
import javax.sql.DataSource;
1819
import java.sql.DriverManager;
1920
import java.sql.ResultSet;
2021
import java.sql.SQLException;
2122
import java.util.ArrayList;
23+
import java.util.HashMap;
2224
import java.util.List;
2325
import java.util.Map;
2426

@@ -47,8 +49,25 @@ public class SchemaRegistry {
4749
@Inject
4850
ProjectService projectService;
4951

52+
@SuppressWarnings("all")
53+
public Map<String, Object> getSystemVariables() {
54+
Map all = new HashMap<>();
55+
all.putAll(System.getenv());
56+
all.putAll(System.getProperties());
57+
Iterable<String> propertyNames = ConfigProvider.getConfig().getPropertyNames();
58+
for (String propertyName : propertyNames) {
59+
if (propertyName.isEmpty()) {
60+
continue;
61+
}
62+
ConfigProvider.getConfig()
63+
.getOptionalValue(propertyName, String.class)
64+
.ifPresent(val -> all.put(propertyName, val));
65+
}
66+
return all;
67+
}
68+
5069
private String getContent(String template) {
51-
return StringUtils.simpleRenderTemplate(template, SystemVariablesHolder.getSystemVariables());
70+
return StringUtils.simpleRenderTemplate(template, getSystemVariables());
5271
}
5372

5473
public List<String> getPhysicsModelNames(Project project) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.flexmodel.common;
2+
3+
import jakarta.enterprise.context.RequestScoped;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
7+
/**
8+
* 请求级别的会话上下文
9+
* <p>
10+
* 由 Quarkus CDI 管理生命周期:每次 HTTP 请求或手动激活的请求上下文会创建一个实例,
11+
* 上下文结束时自动销毁,无需手动 clear()。
12+
* <p>
13+
* 虚拟线程友好:CDI @RequestScoped 由 Quarkus 内部管理上下文激活/停用,
14+
*
15+
* @author cjbi
16+
*/
17+
@RequestScoped
18+
@Getter
19+
@Setter
20+
public class SessionContext {
21+
22+
private String projectId;
23+
private String projectDatabaseName;
24+
private String userId;
25+
26+
}

‎flexmodel-server/src/main/java/dev/flexmodel/common/SessionContextHolder.java‎

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

‎flexmodel-server/src/main/java/dev/flexmodel/common/SystemVariablesHolder.java‎

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

‎flexmodel-server/src/main/java/dev/flexmodel/common/config/web/filter/AuthFilter.java‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import dev.flexmodel.codegen.entity.AuthApiKey;
66
import dev.flexmodel.codegen.entity.AuthProviderConfig;
77
import dev.flexmodel.codegen.entity.Project;
8-
import dev.flexmodel.common.SessionContextHolder;
8+
import dev.flexmodel.common.SessionContext;
99
import dev.flexmodel.common.config.web.jwt.JwtService;
1010
import dev.flexmodel.project.ProjectService;
1111
import dev.flexmodel.projectauth.AuthProviderConfigService;
@@ -44,6 +44,8 @@ public class AuthFilter implements ContainerRequestFilter, ContainerResponseFilt
4444
AuthProviderConfigService authProviderConfigService;
4545
@Inject
4646
JwtService jwtService;
47+
@Inject
48+
SessionContext sessionContext;
4749

4850
@Override
4951
public void filter(ContainerRequestContext requestContext) throws IOException {
@@ -222,10 +224,10 @@ private void fillSessionContextForUser(ContainerRequestContext requestContext, S
222224
if (project == null) {
223225
throw new AuthException("Project not found");
224226
}
225-
SessionContextHolder.setProjectId(projectId);
226-
SessionContextHolder.setProjectDatabaseName(projectService.resolveDatabaseName(projectId));
227+
sessionContext.setProjectId(projectId);
228+
sessionContext.setProjectDatabaseName(projectService.resolveDatabaseName(projectId));
227229
}
228-
SessionContextHolder.setUserId(userId);
230+
sessionContext.setUserId(userId);
229231
requestContext.setProperty("projectId", projectId);
230232
requestContext.setProperty("userId", userId);
231233
}
@@ -240,10 +242,10 @@ private void fillSessionContextForApiKey(ContainerRequestContext requestContext,
240242
if (project == null) {
241243
throw new AuthException("Project not found");
242244
}
243-
SessionContextHolder.setProjectId(projectId);
244-
SessionContextHolder.setProjectDatabaseName(projectService.resolveDatabaseName(projectId));
245+
sessionContext.setProjectId(projectId);
246+
sessionContext.setProjectDatabaseName(projectService.resolveDatabaseName(projectId));
245247
}
246-
SessionContextHolder.setUserId(apiKey.getName());
248+
sessionContext.setUserId(apiKey.getName());
247249
requestContext.setProperty("projectId", projectId);
248250
}
249251

@@ -256,16 +258,17 @@ private void fillSessionContextForProvider(ContainerRequestContext requestContex
256258
if (project == null) {
257259
throw new AuthException("Project not found");
258260
}
259-
SessionContextHolder.setProjectId(projectId);
260-
SessionContextHolder.setProjectDatabaseName(project.getDatabaseName());
261-
SessionContextHolder.setUserId(result.getUserId());
261+
sessionContext.setProjectId(projectId);
262+
sessionContext.setProjectDatabaseName(project.getDatabaseName());
263+
sessionContext.setUserId(result.getUserId());
262264
requestContext.setProperty("projectId", projectId);
263265
}
264266

265267
@Override
266268
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
267269
throws IOException {
268-
SessionContextHolder.clear();
270+
// CDI @RequestScoped 自动管理生命周期,无需手动 clear
271+
// SessionContext 在请求结束时由 CDI 自动销毁
269272
}
270273

271274
}

‎flexmodel-server/src/main/java/dev/flexmodel/flow/consumer/TriggerFlowEventConsumer.java‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package dev.flexmodel.flow.consumer;
22

3+
import dev.flexmodel.common.SessionContext;
4+
import dev.flexmodel.flow.dto.StartProcessParamEvent;
5+
import dev.flexmodel.flow.dto.result.StartProcessResult;
6+
import dev.flexmodel.flow.service.FlowExecutionService;
7+
import dev.flexmodel.scheduling.JobExecutionLogService;
38
import io.quarkus.vertx.ConsumeEvent;
49
import jakarta.enterprise.context.ApplicationScoped;
510
import jakarta.inject.Inject;
611
import lombok.extern.slf4j.Slf4j;
7-
import dev.flexmodel.flow.service.FlowExecutionService;
8-
import dev.flexmodel.flow.dto.StartProcessParamEvent;
9-
import dev.flexmodel.flow.dto.result.StartProcessResult;
10-
import dev.flexmodel.scheduling.JobExecutionLogService;
11-
import dev.flexmodel.common.SessionContextHolder;
1212

1313
/**
1414
* @author cjbi
@@ -23,10 +23,13 @@ public class TriggerFlowEventConsumer {
2323
@Inject
2424
JobExecutionLogService jobExecutionLogService;
2525

26+
@Inject
27+
SessionContext sessionContext;
28+
2629
@ConsumeEvent("flow.start") // 监听特定地址的事件
2730
public void consume(StartProcessParamEvent param) {
28-
SessionContextHolder.setProjectId(param.getProjectId());
29-
SessionContextHolder.setUserId(param.getUserId());
31+
sessionContext.setProjectId(param.getProjectId());
32+
sessionContext.setUserId(param.getUserId());
3033
StartProcessResult result = null;
3134
try {
3235
result = flowExecutionService.startProcess(param);
@@ -39,6 +42,10 @@ public void consume(StartProcessParamEvent param) {
3942
if (param.getEventId() != null) {
4043
jobExecutionLogService.recordJobSuccess(param.getEventId(), result, System.currentTimeMillis() - param.getStartTime());
4144
}
45+
// 清理会话上下文,避免状态泄漏到同一线程的下一次消息处理
46+
sessionContext.setProjectId(null);
47+
sessionContext.setProjectDatabaseName(null);
48+
sessionContext.setUserId(null);
4249
}
4350

4451
}

‎flexmodel-server/src/main/java/dev/flexmodel/flow/service/ProcessEngineImpl.java‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package dev.flexmodel.flow.service;
22

3+
import dev.flexmodel.common.SessionContext;
34
import dev.flexmodel.flow.dto.param.*;
4-
import dev.flexmodel.flow.dto.param.*;
5-
import dev.flexmodel.flow.dto.result.*;
6-
import dev.flexmodel.common.SessionContextHolder;
7-
import jakarta.inject.Inject;
8-
import jakarta.inject.Singleton;
95
import dev.flexmodel.flow.dto.result.*;
106
import dev.flexmodel.flow.processor.DefinitionProcessor;
117
import dev.flexmodel.flow.processor.RuntimeProcessor;
8+
import jakarta.inject.Inject;
9+
import jakarta.inject.Singleton;
1210

1311
@Singleton
1412
public class ProcessEngineImpl implements ProcessService {
@@ -19,24 +17,27 @@ public class ProcessEngineImpl implements ProcessService {
1917
@Inject
2018
RuntimeProcessor runtimeProcessor;
2119

20+
@Inject
21+
SessionContext sessionContext;
22+
2223
@Override
2324
public CreateFlowResult createFlow(CreateFlowParam createFlowParam) {
24-
createFlowParam.setCaller(SessionContextHolder.getUserId());
25-
createFlowParam.setOperator(SessionContextHolder.getUserId());
25+
createFlowParam.setCaller(sessionContext.getUserId());
26+
createFlowParam.setOperator(sessionContext.getUserId());
2627
return definitionProcessor.create(createFlowParam);
2728
}
2829

2930
@Override
3031
public UpdateFlowResult updateFlow(UpdateFlowParam updateFlowParam) {
31-
updateFlowParam.setCaller(SessionContextHolder.getUserId());
32-
updateFlowParam.setOperator(SessionContextHolder.getUserId());
32+
updateFlowParam.setCaller(sessionContext.getUserId());
33+
updateFlowParam.setOperator(sessionContext.getUserId());
3334
return definitionProcessor.update(updateFlowParam);
3435
}
3536

3637
@Override
3738
public DeployFlowResult deployFlow(DeployFlowParam deployFlowParam) {
38-
deployFlowParam.setCaller(SessionContextHolder.getUserId());
39-
deployFlowParam.setOperator(SessionContextHolder.getUserId());
39+
deployFlowParam.setCaller(sessionContext.getUserId());
40+
deployFlowParam.setOperator(sessionContext.getUserId());
4041
return definitionProcessor.deploy(deployFlowParam);
4142
}
4243

0 commit comments

Comments
 (0)