From 28233132c3c8527639262edf473b07d53bb2019e Mon Sep 17 00:00:00 2001 From: tursom Date: Mon, 9 Mar 2020 18:08:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=B7=AF=E7=94=B1=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=99=A8=E6=B7=BB=E5=8A=A0=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/cn/tursom/core/Tools.kt | 5 +- .../cn/tursom/web/router/RoutedHttpHandler.kt | 68 +++++++++++-------- .../web/router/AsyncRoutedHttpHandler.kt | 15 +++- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/cn/tursom/core/Tools.kt b/src/main/kotlin/cn/tursom/core/Tools.kt index 158058f..6f49291 100644 --- a/src/main/kotlin/cn/tursom/core/Tools.kt +++ b/src/main/kotlin/cn/tursom/core/Tools.kt @@ -256,4 +256,7 @@ inline fun loop(`continue`: () -> Boolean = { true }, action: () -> Unit) { while (`continue`()) action() } -inline fun getClazz() = T::class.java \ No newline at end of file +inline fun getClazz() = T::class.java + +@Suppress("NOTHING_TO_INLINE") +inline fun > lambda(lambda: T) = lambda \ No newline at end of file diff --git a/web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt b/web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt index a4a4a87..0918c05 100644 --- a/web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt +++ b/web/src/main/kotlin/cn/tursom/web/router/RoutedHttpHandler.kt @@ -1,6 +1,8 @@ package cn.tursom.web.router import cn.tursom.core.buffer.ByteBuffer +import cn.tursom.core.cast +import cn.tursom.core.lambda import cn.tursom.core.regex.regex import cn.tursom.json.JsonWorkerImpl import cn.tursom.web.ExceptionContent @@ -11,9 +13,9 @@ import cn.tursom.web.mapping.* import cn.tursom.web.result.* import cn.tursom.web.router.impl.SimpleRouter import cn.tursom.web.utils.Chunked +import cn.tursom.web.utils.ContextTypeEnum import org.slf4j.LoggerFactory -import java.io.File -import java.io.RandomAccessFile +import java.io.* import java.lang.reflect.Method import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.ThreadFactory @@ -40,7 +42,7 @@ open class RoutedHttpHandler( Runtime.getRuntime().availableProcessors() * 4, Runtime.getRuntime().availableProcessors() * 4, 0L, TimeUnit.MILLISECONDS, - LinkedBlockingQueue(), + LinkedBlockingQueue(), ThreadFactory { Thread(it, "TreeDiagramWorker-${threadNumber.incrementAndGet()}") } @@ -61,7 +63,16 @@ open class RoutedHttpHandler( open fun handle(content: HttpContent, handler: ((HttpContent) -> Any?)?) { if (handler != null) { - handler(content) + try { + handler(content) + } catch (e: Throwable) { + val bos = ByteArrayOutputStream() + bos.write("处理时发生异常:\n".toByteArray()) + e.printStackTrace(PrintStream(bos)) + content.setContextType(ContextTypeEnum.txt.value) + content.write(bos.toByteArray()) + content.finish(502) + } } else { notFound(content) } @@ -128,44 +139,43 @@ open class RoutedHttpHandler( } } + @Suppress("UNREACHABLE_CODE") fun addRouter(obj: Any, method: Method, route: String, router: Router Any?>>) { val doLog = method.doLog - router[safeRoute(route)] = obj to (if (method.parameterTypes.isEmpty()) { - when { - method.getAnnotation(Html::class.java) != null -> { content -> - method(obj)?.let { result -> finishHtml(result, content, doLog) } - } - method.getAnnotation(Text::class.java) != null -> { content -> - method(obj)?.let { result -> finishText(result, content, doLog) } - } - method.getAnnotation(Json::class.java) != null -> { content -> - method(obj)?.let { result -> finishJson(result, content, doLog) } - } - else -> { content -> - method(obj)?.let { result -> autoReturn(method, result, content, doLog) } - } - } - } else when (method.returnType) { - Void::class.java -> { content -> method(obj, content) } - Void.TYPE -> { content -> method(obj, content) } - Unit::class.java -> { content -> method(obj, content) } + router[safeRoute(route)] = obj to (if (method.parameterTypes.isNotEmpty()) when (method.returnType) { + Void::class.java -> lambda { content: HttpContent -> method(obj, content) } + Void.TYPE -> lambda { content: HttpContent -> method(obj, content) } + Unit::class.java -> lambda { content: HttpContent -> method(obj, content) } else -> when { - method.getAnnotation(Html::class.java) != null -> { content -> + method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent -> method(obj, content)?.let { result -> finishHtml(result, content, doLog) } } - method.getAnnotation(Text::class.java) != null -> { content -> + method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent -> method(obj, content)?.let { result -> finishText(result, content, doLog) } } - method.getAnnotation(Json::class.java) != null -> { content -> + method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent -> method(obj, content)?.let { result -> finishJson(result, content, doLog) } } - else -> { content: HttpContent -> + else -> lambda { content: HttpContent -> method(obj, content)?.let { result -> autoReturn(method, result, content, doLog) } } } + } else when { + method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent -> + method(obj)?.let { result -> finishHtml(result, content, doLog) } + } + method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent -> + method(obj)?.let { result -> finishText(result, content, doLog) } + } + method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent -> + method(obj)?.let { result -> finishJson(result, content, doLog) } + } + else -> lambda { content: HttpContent -> + method(obj)?.let { result -> autoReturn(method, result, content, doLog) } + } }).let { - if (method.getAnnotation(BlockHandler::class.java) != null) { content -> - workerThread.execute { it(content) } + if (method.getAnnotation(BlockHandler::class.java) != null) lambda { content -> + workerThread.execute { handle(content, it) } } else it } diff --git a/web/web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt b/web/web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt index 88260e7..ee7f3ee 100644 --- a/web/web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt +++ b/web/web-coroutine/src/main/kotlin/cn/tursom/web/router/AsyncRoutedHttpHandler.kt @@ -5,9 +5,12 @@ import cn.tursom.web.MutableHttpContent import cn.tursom.web.mapping.* import cn.tursom.web.result.* import cn.tursom.web.router.impl.SimpleRouter +import cn.tursom.web.utils.ContextTypeEnum import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.slf4j.LoggerFactory +import java.io.ByteArrayOutputStream +import java.io.PrintStream import kotlin.reflect.KCallable import kotlin.reflect.full.findAnnotation import kotlin.reflect.jvm.jvmErasure @@ -41,7 +44,17 @@ open class AsyncRoutedHttpHandler( open suspend fun handle(content: HttpContent, handler: (suspend (HttpContent) -> Unit)?) { if (handler != null) { - handler(content) + try { + handler(content) + } catch (e: Throwable) { + val bos = ByteArrayOutputStream() + @Suppress("BlockingMethodInNonBlockingContext") + bos.write("处理时发生异常:\n".toByteArray()) + e.printStackTrace(PrintStream(bos)) + content.setContextType(ContextTypeEnum.txt.value) + content.write(bos.toByteArray()) + content.finish(502) + } } else { notFound(content) }