feat(context): 添加协程上下文工具类并优化追踪ID获取逻辑

This commit is contained in:
gewuyou 2025-07-18 04:31:36 +00:00
parent d4399d9fd4
commit b27d84f3c1
6 changed files with 59 additions and 48 deletions

View File

@ -1,5 +1,4 @@
stages: stages:
- build
- tag - tag
- publish - publish
- reset - reset
@ -11,34 +10,9 @@ variables:
before_script: before_script:
- rm -rf $GRADLE_USER_HOME/.tmp || true - rm -rf $GRADLE_USER_HOME/.tmp || true
# ✅ Build 阶段
build:
stage: build
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
cache:
key:
files:
- gradle/libs.versions.toml
- "**/*.gradle.kts"
prefix: lab-agent
paths:
- .gradle/caches/
- .gradle/wrapper/
- .gradle/kotlin-profile/
- .kotlin/
policy: pull-push
script:
- echo "🔧 授予 gradlew 执行权限..."
- chmod +x gradlew
- ./gradlew clean build
tags:
- java
# 🏷️ 自动打标签 # 🏷️ 自动打标签
tag: tag:
stage: tag stage: tag
needs: [ "build" ]
image: alpine:latest image: alpine:latest
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'
@ -82,6 +56,18 @@ publish:
needs: [ "tag" ] needs: [ "tag" ]
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'
cache:
key:
files:
- gradle/libs.versions.toml
- "**/*.gradle.kts"
prefix: lab-agent
paths:
- .gradle/caches/
- .gradle/wrapper/
- .gradle/kotlin-profile/
- .kotlin/
policy: pull-push
script: script:
- echo "🔧 授予 gradlew 执行权限..." - echo "🔧 授予 gradlew 执行权限..."
- chmod +x gradlew - chmod +x gradlew
@ -92,7 +78,7 @@ publish:
# 🔄 重建 test 分支 # 🔄 重建 test 分支
reset: reset:
stage: reset stage: reset
needs: [ "build" ] needs: [ "publish" ]
image: alpine:latest image: alpine:latest
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'
@ -111,7 +97,7 @@ reset:
# Mirror to GitHub # Mirror to GitHub
mirror-to-github: mirror-to-github:
stage: mirror stage: mirror
needs: [ "build" ] needs: [ "publish" ]
image: alpine:latest image: alpine:latest
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'

View File

@ -1,23 +1,9 @@
stages: stages:
- build
- publish - publish
# 🧪 test 构建
build:
stage: build
rules:
- if: '$CI_COMMIT_BRANCH == "test"'
script:
- echo "🔧 授予 gradlew 执行权限..."
- chmod +x gradlew
- ./gradlew clean build
tags:
- java
# 🧪 test 发布 SNAPSHOT 包(允许覆盖) # 🧪 test 发布 SNAPSHOT 包(允许覆盖)
publish: publish:
stage: publish stage: publish
needs: ["build"]
rules: rules:
- if: '$CI_COMMIT_BRANCH == "test"' - if: '$CI_COMMIT_BRANCH == "test"'
script: script:

View File

@ -0,0 +1,36 @@
package com.gewuyou.forgeboot.context.impl.utils
import com.gewuyou.forgeboot.context.api.ContextProcessor
import com.gewuyou.forgeboot.context.impl.ContextHolder
import com.gewuyou.forgeboot.context.impl.coroutine.ContextAwareCoroutineScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
/**
* 协程上下文工具类用于在特定上下文中启动协程任务
*
* @since 2025-07-18 11:17:44
* @author gewuyou
*/
object CoroutineContextUtils {
/**
* 在指定的上下文中启动一个协程任务并返回对应的 Job 对象
*
* @param contextHolder 上下文持有者用于管理上下文数据的生命周期
* @param processors 上下文处理器列表用于处理上下文相关的逻辑
* @param dispatcher 协程调度器决定协程在哪个线程或线程池中执行默认为 [Dispatchers.Default]
* @param block 要执行的协程代码块接收一个挂起的 [CoroutineScope] 扩展函数
*
* @return 返回一个 [Job] 对象可用于取消或跟踪协程任务的状态
*/
fun launchWithScopedContext(
contextHolder: ContextHolder,
processors: List<ContextProcessor>,
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: suspend CoroutineScope.() -> Unit,
): Job {
return ContextAwareCoroutineScope(contextHolder, processors).launchWithContext(dispatcher, block)
}
}

View File

@ -1,8 +1,8 @@
dependencies { dependencies {
implementation(libs.springBootStarter.web) implementation(libs.springBootStarter.web)
implementation(project(Modules.TRACE.STARTER)) implementation(project(Modules.TRACE.STARTER))
implementation(project(Modules.Context.STARTER)) implementation(project(Modules.Context.STARTER))
implementation(project(Modules.Webmvc.DTO))
implementation(libs.kotlinxCoroutines.reactor) implementation(libs.kotlinxCoroutines.reactor)
implementation(libs.kotlinxCoroutines.core) implementation(libs.kotlinxCoroutines.core)
} }

View File

@ -5,6 +5,7 @@ import com.gewuyou.forgeboot.context.impl.ContextHolder
import com.gewuyou.forgeboot.context.impl.coroutine.ContextAwareCoroutineScope import com.gewuyou.forgeboot.context.impl.coroutine.ContextAwareCoroutineScope
import com.gewuyou.forgeboot.core.extension.log import com.gewuyou.forgeboot.core.extension.log
import com.gewuyou.forgeboot.trace.api.RequestIdProvider import com.gewuyou.forgeboot.trace.api.RequestIdProvider
import com.gewuyou.forgeboot.webmvc.dto.R
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@ -23,7 +24,7 @@ class TraceTestController(
private val processors: List<ContextProcessor>, private val processors: List<ContextProcessor>,
) { ) {
@GetMapping("/coroutine") @GetMapping("/coroutine")
suspend fun coroutine(): String { suspend fun coroutine(): R<String> {
val requestId = requestIdProvider.getRequestId() val requestId = requestIdProvider.getRequestId()
log.info("→ Controller RequestId: $requestId") log.info("→ Controller RequestId: $requestId")
@ -32,7 +33,7 @@ class TraceTestController(
scope.launchWithContext { scope.launchWithContext {
log.info("RID: ${requestIdProvider.getRequestId()}") log.info("RID: ${requestIdProvider.getRequestId()}")
} }
return "Main coroutine returned immediately with requestId: $requestId" return R.success("Main coroutine returned immediately with requestId: $requestId",requestIdProvider = requestIdProvider)
} }
@GetMapping("/servlet") @GetMapping("/servlet")

View File

@ -4,6 +4,7 @@ import com.gewuyou.forgeboot.context.api.extension.get
import com.gewuyou.forgeboot.context.impl.ContextHolder import com.gewuyou.forgeboot.context.impl.ContextHolder
import com.gewuyou.forgeboot.trace.api.RequestIdProvider import com.gewuyou.forgeboot.trace.api.RequestIdProvider
import com.gewuyou.forgeboot.trace.api.config.TraceProperties import com.gewuyou.forgeboot.trace.api.config.TraceProperties
import org.slf4j.MDC
/** /**
@ -14,8 +15,8 @@ import com.gewuyou.forgeboot.trace.api.config.TraceProperties
*/ */
class TraceRequestIdProvider( class TraceRequestIdProvider(
private val traceProperties: TraceProperties, private val traceProperties: TraceProperties,
private val contextHolder: ContextHolder private val contextHolder: ContextHolder,
): RequestIdProvider { ) : RequestIdProvider {
/** /**
* 获取请求ID * 获取请求ID
* *
@ -24,6 +25,7 @@ class TraceRequestIdProvider(
* @return 请求ID的字符串表示 * @return 请求ID的字符串表示
*/ */
override fun getRequestId(): String { override fun getRequestId(): String {
return contextHolder[traceProperties.requestIdMdcKey] ?:throw RuntimeException("requestId is null") return contextHolder[traceProperties.requestIdMdcKey] ?: MDC.get(traceProperties.requestIdMdcKey)
?: throw RuntimeException("requestId is null")
} }
} }