From 993de664d9be73c8f64ba7301b0f8b195cc56bdd Mon Sep 17 00:00:00 2001 From: tursom Date: Tue, 11 May 2021 15:14:09 +0800 Subject: [PATCH] update --- .../cn/tursom/core}/InstantAllocator.kt | 4 +-- .../src/main/kotlin/cn/tursom/core/Parser.kt | 7 ++--- .../cn/tursom/core/clone/cloneBackend.kt | 5 +--- .../cn/tursom/core/ws/WebSocketClient.kt | 6 ++-- .../core/ws/WebSocketClientChannelHandler.kt | 8 +++-- .../cn/tursom/database/TypeAdapterFactory.kt | 2 +- .../cn/tursom/web/router/MappedMethod.kt | 8 +++++ .../cn/tursom/web/router/RoutedHttpHandler.kt | 29 +++++++++++------- .../kotlin/cn/tursom/web/router/WebAspect.kt | 5 ++++ .../web/router/AsyncRoutedHttpHandler.kt | 30 ++++++++++++------- ts-web/ts-web-netty/build.gradle.kts | 12 ++++---- 11 files changed, 72 insertions(+), 44 deletions(-) rename ts-core/{ts-clone/src/main/kotlin/cn/tursom/core/clone => src/main/kotlin/cn/tursom/core}/InstantAllocator.kt (95%) create mode 100644 ts-web/src/main/kotlin/cn/tursom/web/router/MappedMethod.kt create mode 100644 ts-web/src/main/kotlin/cn/tursom/web/router/WebAspect.kt diff --git a/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/InstantAllocator.kt b/ts-core/src/main/kotlin/cn/tursom/core/InstantAllocator.kt similarity index 95% rename from ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/InstantAllocator.kt rename to ts-core/src/main/kotlin/cn/tursom/core/InstantAllocator.kt index 929472a..d279c8f 100644 --- a/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/InstantAllocator.kt +++ b/ts-core/src/main/kotlin/cn/tursom/core/InstantAllocator.kt @@ -1,7 +1,5 @@ -package cn.tursom.core.clone +package cn.tursom.core -import cn.tursom.core.Unsafe -import cn.tursom.core.uncheckedCast import java.util.concurrent.ConcurrentHashMap import kotlin.reflect.KClass diff --git a/ts-core/src/main/kotlin/cn/tursom/core/Parser.kt b/ts-core/src/main/kotlin/cn/tursom/core/Parser.kt index 5272df7..f2f7083 100644 --- a/ts-core/src/main/kotlin/cn/tursom/core/Parser.kt +++ b/ts-core/src/main/kotlin/cn/tursom/core/Parser.kt @@ -66,11 +66,8 @@ object Parser { else -> { if (yaml !is Map<*, *>) return null - val instance = try { - clazz.newInstance() - } catch (e: Exception) { - unsafe.allocateInstance(clazz) - } + + val instance = InstantAllocator[clazz] val fields = clazz.declaredFields fields.forEach { if ((it.modifiers and (Modifier.STATIC or Modifier.TRANSIENT)) != 0) return@forEach diff --git a/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/cloneBackend.kt b/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/cloneBackend.kt index fa81114..d36aa9a 100644 --- a/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/cloneBackend.kt +++ b/ts-core/ts-clone/src/main/kotlin/cn/tursom/core/clone/cloneBackend.kt @@ -1,11 +1,8 @@ package cn.tursom.core.clone -import cn.tursom.core.Unsafe -import cn.tursom.core.allMemberProperties +import cn.tursom.core.* import cn.tursom.core.datastruct.KPropertyValueMap import cn.tursom.core.datastruct.SoftArrayMap -import cn.tursom.core.unaryPlus -import cn.tursom.core.uncheckedCast import cn.tursom.log.impl.Slf4jImpl import java.util.concurrent.ConcurrentHashMap import kotlin.collections.component1 diff --git a/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClient.kt b/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClient.kt index c308ce3..98dea5b 100644 --- a/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClient.kt +++ b/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClient.kt @@ -106,13 +106,15 @@ class WebSocketClient( //handler.handshakeFuture().sync() } - fun close(reasonText: String? = null) { + fun close(reasonText: String? = null): ChannelFuture? { if (reasonText == null) { ch?.writeAndFlush(CloseWebSocketFrame()) } else { ch?.writeAndFlush(CloseWebSocketFrame(WebSocketCloseStatus.NORMAL_CLOSURE, reasonText)) } - ch?.closeFuture()?.sync() + ch?.close() + return ch?.closeFuture() + //ch?.closeFuture()?.sync() } fun write(text: String): ChannelFuture { diff --git a/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClientChannelHandler.kt b/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClientChannelHandler.kt index 099cb8c..75bee11 100644 --- a/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClientChannelHandler.kt +++ b/ts-core/ts-ws-client/src/main/kotlin/cn/tursom/core/ws/WebSocketClientChannelHandler.kt @@ -8,7 +8,7 @@ import io.netty.handler.codec.http.websocketx.* class WebSocketClientChannelHandler( val client: WebSocketClient, val handler: WebSocketHandler, - autoRelease: Boolean = true, + private val autoRelease: Boolean = true, ) : SimpleChannelInboundHandler(autoRelease) { override fun channelInactive(ctx: ChannelHandlerContext) { @@ -25,7 +25,11 @@ class WebSocketClientChannelHandler( is BinaryWebSocketFrame -> handler.readMessage(client, msg) is PingWebSocketFrame -> handler.readPing(client, msg) is PongWebSocketFrame -> handler.readPong(client, msg) - is CloseWebSocketFrame -> ch.close() + is CloseWebSocketFrame -> { + if (!autoRelease) while (msg.refCnt() != 0) msg.release() + ch.close() + } + else -> if (!autoRelease) while (msg.refCnt() != 0) msg.release() } } } \ No newline at end of file diff --git a/ts-database/src/main/kotlin/cn/tursom/database/TypeAdapterFactory.kt b/ts-database/src/main/kotlin/cn/tursom/database/TypeAdapterFactory.kt index dc0a828..ffd5891 100644 --- a/ts-database/src/main/kotlin/cn/tursom/database/TypeAdapterFactory.kt +++ b/ts-database/src/main/kotlin/cn/tursom/database/TypeAdapterFactory.kt @@ -1,6 +1,6 @@ package cn.tursom.database -import cn.tursom.core.clone.InstantAllocator +import cn.tursom.core.InstantAllocator import cn.tursom.core.getClassByPackage import cn.tursom.core.uncheckedCast import me.liuwj.ktorm.schema.BaseTable diff --git a/ts-web/src/main/kotlin/cn/tursom/web/router/MappedMethod.kt b/ts-web/src/main/kotlin/cn/tursom/web/router/MappedMethod.kt new file mode 100644 index 0000000..2c14a18 --- /dev/null +++ b/ts-web/src/main/kotlin/cn/tursom/web/router/MappedMethod.kt @@ -0,0 +1,8 @@ +package cn.tursom.web.router + +import java.lang.reflect.Method + +data class MappedMethod( + val method: Method, + val aspect: List +) \ No newline at end of file diff --git a/ts-web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt b/ts-web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt index 8423aba..e5d6fc6 100644 --- a/ts-web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt +++ b/ts-web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt @@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger */ @Suppress("MemberVisibilityCanBePrivate", "unused") open class RoutedHttpHandler( - target: Any? = null, + vararg target: Any, val routerMaker: () -> Router Any?>> = { SimpleRouter() } ) : HttpHandler { protected val router: Router Any?>> = routerMaker() @@ -52,7 +52,11 @@ open class RoutedHttpHandler( init { @Suppress("LeakingThis") - addRouter(target ?: this) + if ((target.isEmpty())) { + addRouter(this) + } else { + target.forEach(::addRouter) + } } override fun handle(content: HttpContent) { @@ -150,30 +154,30 @@ open class RoutedHttpHandler( Unit::class.java -> lambda { content: HttpContent -> method(obj, content) } else -> when { method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent -> - method(obj, content)?.let { result -> finishHtml(result, content, doLog) } + finishHtml(method(obj, content), content, doLog) } method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent -> - method(obj, content)?.let { result -> finishText(result, content, doLog) } + finishText(method(obj, content), content, doLog) } method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent -> - method(obj, content)?.let { result -> finishJson(result, content, doLog) } + finishJson(method(obj, content), content, doLog) } else -> lambda { content: HttpContent -> - method(obj, content)?.let { result -> autoReturn(method, result, content, doLog) } + autoReturn(method, method(obj, content), content, doLog) } } } else when { method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent -> - method(obj)?.let { result -> finishHtml(result, content, doLog) } + finishHtml(method(obj), content, doLog) } method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent -> - method(obj)?.let { result -> finishText(result, content, doLog) } + finishText(method(obj), content, doLog) } method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent -> - method(obj)?.let { result -> finishJson(result, content, doLog) } + finishJson(method(obj), content, doLog) } else -> lambda { content: HttpContent -> - method(obj)?.let { result -> autoReturn(method, result, content, doLog) } + autoReturn(method, method(obj), content, doLog) } }).let { if (method.getAnnotation(BlockHandler::class.java) != null) lambda { content -> @@ -282,6 +286,7 @@ open class RoutedHttpHandler( }.repeatUntil({ it.contains("//") }) { it.replace(slashRegex, "/") } fun autoReturn(method: Method, result: Any?, content: HttpContent, doLog: Boolean? = null) { + if (content.finished || result is Unit) return method.getAnnotation(ContextType::class.java)?.let { content.setContextType(it.type.value) log?.debug("{}: autoReturn context type auto set to {}({})", content.remoteAddress, it.type.key, it.type.value) @@ -290,6 +295,7 @@ open class RoutedHttpHandler( } fun autoReturn(result: Any?, content: HttpContent, doLog: Boolean = true) { + if (content.finished || result is Unit) return if (doLog) log?.debug("{}: autoReturn: {}", content.remoteAddress, result) result ?: return when (result) { @@ -312,6 +318,7 @@ open class RoutedHttpHandler( } fun finishHtml(result: Any?, content: HttpContent, doLog: Boolean = true) { + if (content.finished || result is Unit) return if (doLog) log?.debug("{} finishHtml {}", content.remoteAddress, result) result ?: return when (result) { @@ -330,6 +337,7 @@ open class RoutedHttpHandler( } fun finishText(result: Any?, content: HttpContent, doLog: Boolean = true) { + if (content.finished || result is Unit) return if (doLog) log?.debug("{} finishText {}", content.remoteAddress, result) result ?: return when (result) { @@ -348,6 +356,7 @@ open class RoutedHttpHandler( } fun finishJson(result: Any?, content: HttpContent, doLog: Boolean = true) { + if (content.finished || result is Unit) return if (doLog) log?.debug("{} finishJson {}", content.remoteAddress, result) result ?: return when (result) { diff --git a/ts-web/src/main/kotlin/cn/tursom/web/router/WebAspect.kt b/ts-web/src/main/kotlin/cn/tursom/web/router/WebAspect.kt new file mode 100644 index 0000000..4125bd6 --- /dev/null +++ b/ts-web/src/main/kotlin/cn/tursom/web/router/WebAspect.kt @@ -0,0 +1,5 @@ +package cn.tursom.web.router + +interface WebAspect { + +} \ No newline at end of file diff --git a/ts-web/ts-web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt b/ts-web/ts-web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt index 70ab0ba..e0c1cae 100644 --- a/ts-web/ts-web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt +++ b/ts-web/ts-web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt @@ -17,7 +17,7 @@ import kotlin.reflect.jvm.jvmErasure @Suppress("ProtectedInFinal", "unused", "MemberVisibilityCanBePrivate") open class AsyncRoutedHttpHandler( - target: Any? = null, + vararg target: Any, routerMaker: () -> Router Any?>> = { SimpleRouter() }, val asyncRouterMaker: () -> Router Unit>> = { SimpleRouter() } ) : RoutedHttpHandler(target, routerMaker) { @@ -60,7 +60,10 @@ open class AsyncRoutedHttpHandler( } } - fun getAsyncHandler(method: String, route: String): Pair Unit>?, List>> { + fun getAsyncHandler( + method: String, + route: String + ): Pair Unit>?, List>> { val safeRoute = safeRoute(route) val router = getAsyncRouter(method)[safeRoute] return if (router.first != null) router else this.asyncRouter[safeRoute] @@ -110,21 +113,26 @@ open class AsyncRoutedHttpHandler( } @Suppress("UNCHECKED_CAST") - fun addRouter(obj: Any, method: KCallable<*>, route: String, router: Router Unit>>) { + fun addRouter( + obj: Any, + method: KCallable<*>, + route: String, + router: Router Unit>> + ) { val doLog = method.doLog router[safeRoute(route)] = if (method.parameters.size == 1) { obj to when { method.findAnnotation() != null -> { content -> - (method as suspend Any.() -> Any?)(obj)?.let { result -> finishHtml(result, content, doLog) } + finishHtml((method as suspend Any.() -> Any?)(obj), content, doLog) } method.findAnnotation() != null -> { content -> - (method as suspend Any.() -> Any?)(obj)?.let { result -> finishText(result, content, doLog) } + finishText((method as suspend Any.() -> Any?)(obj), content, doLog) } method.findAnnotation() != null -> { content -> - (method as suspend Any.() -> Any?)(obj)?.let { result -> finishJson(result, content, doLog) } + finishJson((method as suspend Any.() -> Any?)(obj), content, doLog) } else -> { content -> - (method as suspend Any.() -> Any?)(obj)?.let { result -> autoReturn(method, result, content, doLog) } + autoReturn(method, (method as suspend Any.() -> Any?)(obj), content, doLog) } } } else obj to when (method.returnType.jvmErasure.java) { @@ -133,16 +141,16 @@ open class AsyncRoutedHttpHandler( Unit::class.java -> { content -> (method as suspend Any.(HttpContent) -> Unit)(obj, content) } else -> when { method.findAnnotation() != null -> { content -> - (method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishHtml(result, content, doLog) } + finishHtml((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog) } method.findAnnotation() != null -> { content -> - (method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishText(result, content, doLog) } + finishText((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog) } method.findAnnotation() != null -> { content -> - (method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishJson(result, content, doLog) } + finishJson((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog) } else -> { content -> - (method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> autoReturn(method, result, content, doLog) } + autoReturn(method, (method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog) } } } diff --git a/ts-web/ts-web-netty/build.gradle.kts b/ts-web/ts-web-netty/build.gradle.kts index 0a2e69a..c10f3a6 100644 --- a/ts-web/ts-web-netty/build.gradle.kts +++ b/ts-web/ts-web-netty/build.gradle.kts @@ -4,12 +4,12 @@ plugins { } dependencies { - implementation(project(":ts-core")) - implementation(project(":ts-core:ts-buffer")) - implementation(project(":ts-core:ts-log")) - implementation(project(":ts-web")) - implementation(group = "io.netty", name = "netty-all", version = "4.1.43.Final") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.29") + api(project(":ts-core")) + api(project(":ts-core:ts-buffer")) + api(project(":ts-core:ts-log")) + api(project(":ts-web")) + api(group = "io.netty", name = "netty-all", version = "4.1.43.Final") + api(group = "org.slf4j", name = "slf4j-api", version = "1.7.29") } @kotlin.Suppress("UNCHECKED_CAST")