Skip to content

Commit 08006fc

Browse files
bjhhamosipxd
andauthored
KTOR-9054 Fix application call coroutine context (#5170)
* KTOR-9054 Fix application call coroutine context * KTOR-9054 Fixup Jetty engine coroutines * Update ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt Co-authored-by: Osip Fatkullin <osip.fatkullin@jetbrains.com> * Disable tomcat coroutine hierarchy check --------- Co-authored-by: Osip Fatkullin <osip.fatkullin@jetbrains.com>
1 parent 2867154 commit 08006fc

File tree

17 files changed

+95
-22
lines changed

17 files changed

+95
-22
lines changed

ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/CIOEngineTestJvm.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class CIOSustainabilityTest : SustainabilityTestSuite<CIOApplicationEngine, CIOA
4646
enableHttp2 = false
4747
enableSsl = false
4848
}
49+
50+
@Ignore
51+
override fun validateCallCoroutineContext() {}
4952
}
5053

5154
class CIOConfigTest : ConfigTestSuite(CIO)

ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPipelineCall.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ import kotlin.coroutines.*
2323
public class RoutingPipelineCall(
2424
public val engineCall: PipelineCall,
2525
public val route: RoutingNode,
26+
override val coroutineContext: CoroutineContext,
2627
receivePipeline: ApplicationReceivePipeline,
2728
responsePipeline: ApplicationSendPipeline,
2829
public val pathParameters: Parameters
2930
) : PipelineCall, CoroutineScope {
30-
@Deprecated(level = DeprecationLevel.WARNING, message = "CoroutineContext is delegated to engineCall now.")
31+
@Deprecated(level = DeprecationLevel.WARNING, message = "Use explicit coroutineContext instead.")
3132
public constructor(
3233
engineCall: PipelineCall,
3334
route: RoutingNode,
34-
coroutineContext: CoroutineContext,
3535
receivePipeline: ApplicationReceivePipeline,
3636
responsePipeline: ApplicationSendPipeline,
3737
pathParameters: Parameters
3838
) : this(
3939
engineCall,
4040
route,
41+
engineCall.coroutineContext,
4142
receivePipeline,
4243
responsePipeline,
4344
pathParameters
4445
)
4546

4647
override val application: Application get() = engineCall.application
4748
override val attributes: Attributes get() = engineCall.attributes
48-
override val coroutineContext: CoroutineContext get() = engineCall.coroutineContext
4949

5050
override val request: RoutingPipelineRequest =
5151
RoutingPipelineRequest(this, receivePipeline, engineCall.request)

ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public class RoutingRoot(
9494
val routingApplicationCall = RoutingPipelineCall(
9595
context.call,
9696
route,
97+
context.coroutineContext,
9798
receivePipeline,
9899
responsePipeline,
99100
parameters

ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.eclipse.jetty.server.Response
1717
import org.eclipse.jetty.util.Callback
1818
import java.util.concurrent.*
1919
import java.util.concurrent.atomic.AtomicLong
20+
import kotlin.coroutines.CoroutineContext
2021

2122
private val JettyCallHandlerCoroutineName = CoroutineName("jetty-call-handler")
2223
private val JettyKtorCounter = AtomicLong()
@@ -41,17 +42,16 @@ internal class JettyKtorHandler(
4142
Thread(r, "ktor-jetty-$environmentName-${JettyKtorCounter.incrementAndGet()}")
4243
}
4344
private val dispatcher = executor.asCoroutineDispatcher()
44-
45-
private val handlerJob = SupervisorJob(applicationProvider().parentCoroutineContext[Job])
46-
private val coroutineScope: CoroutineScope =
47-
applicationProvider() + handlerJob + DefaultUncaughtExceptionHandler(environment.log)
45+
private val handlerContext: CoroutineContext = dispatcher +
46+
DefaultUncaughtExceptionHandler(environment.log) +
47+
JettyCallHandlerCoroutineName
4848

4949
override fun destroy() {
5050
try {
5151
super.destroy()
5252
executor.shutdownNow()
5353
} finally {
54-
handlerJob.cancel()
54+
handlerContext.cancel()
5555
}
5656
}
5757

@@ -61,14 +61,15 @@ internal class JettyKtorHandler(
6161
callback: Callback,
6262
): Boolean {
6363
try {
64-
coroutineScope.launch(dispatcher + JettyCallHandlerCoroutineName) {
64+
val application = applicationProvider()
65+
application.launch(handlerContext) {
6566
val call = JettyApplicationCall(
66-
applicationProvider(),
67+
application,
6768
request,
6869
response,
6970
executor = executor,
70-
userContext = dispatcher,
71-
coroutineContext = this@launch.coroutineContext,
71+
userContext = application.coroutineContext,
72+
coroutineContext = currentCoroutineContext(),
7273
idleTimeout = configuration.idleTimeout
7374
)
7475

ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyAsyncServletContainerTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ class JettyAsyncServletContainerHttpServerJvmTest :
4444
class JettyAsyncServletContainerSustainabilityTest :
4545
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
4646
Servlet(async = true)
47-
)
47+
) {
48+
@Ignore
49+
override fun validateCallCoroutineContext() {}
50+
}
4851

4952
class JettyAsyncServerPluginsTest :
5053
ServerPluginsTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(

ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyBlockingServletContainerTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class JettyBlockingServletContainerHttpServerJvmTest :
4545
class JettyBlockingServletContainerSustainabilityTest :
4646
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
4747
Servlet(async = false)
48-
)
48+
) {
49+
@Ignore
50+
override fun validateCallCoroutineContext() {}
51+
}
4952

5053
class JettyBlockingServletServerPluginTest :
5154
ServerPluginsTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(

ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletAsyncTest.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,9 @@ class JettyHttp2AsyncServletContainerHttpServerJvmTest :
3737
}
3838

3939
class JettyHttp2AsyncServletContainerSustainabilityTest :
40-
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(Servlet(async = true))
40+
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
41+
Servlet(async = true)
42+
) {
43+
@Ignore
44+
override fun validateCallCoroutineContext() {}
45+
}

ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletBlockingTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ class JettyHttp2BlockingServletContainerHttpServerJvmTest :
4444
class JettyHttp2BlockingServletContainerSustainabilityTest :
4545
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
4646
Servlet(async = false)
47-
)
47+
) {
48+
@Ignore
49+
override fun validateCallCoroutineContext() {}
50+
}

ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ class JettyAsyncServletContainerHttpServerJvmTest :
3737
}
3838

3939
class JettyAsyncServletContainerSustainabilityTest :
40-
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(Servlet(async = true))
40+
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
41+
Servlet(async = true)
42+
) {
43+
@Ignore
44+
override fun validateCallCoroutineContext() {}
45+
}
4146

4247
class JettyAsyncServerPluginsTest :
4348
ServerPluginsTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(

ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ class JettyBlockingServletContainerHttpServerJvmTest :
4444
class JettyBlockingServletContainerSustainabilityTest :
4545
SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
4646
Servlet(async = false)
47-
)
47+
) {
48+
@Ignore
49+
override fun validateCallCoroutineContext() {}
50+
}
4851

4952
class JettyBlockingServletServerPluginTest :
5053
ServerPluginsTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(

0 commit comments

Comments
 (0)