-
Notifications
You must be signed in to change notification settings - Fork 921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix bug related with context propagation (CoroutineServerInterceptor) #4894
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
e4aad71
Fix bug related with context propagation (CoroutineServerInterceptor)
be-hase 2f18c5f
apply review feedback
be-hase dd0fdf5
Merge branch 'main' into issue-4889
ikhoon e2af251
Fix ArmeriaCoroutineContextInterceptor
ikhoon eb1ac00
lint
ikhoon c4cc245
add a workaround for a wrapped 'ServerCall'
ikhoon def7f49
clean up
ikhoon 7396066
fix broken tests
ikhoon c2d1dd3
use getter instead of field access
ikhoon 89e9b1f
Address comments by @be-hase
ikhoon b89d2fd
Merge branch 'main' into issue-4889
ikhoon d8c3d4f
lint
ikhoon cac81dd
Merge branch 'issue-4889' of github.com:be-hase/armeria into pr-4894-…
ikhoon 2d2fa46
lint
ikhoon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,18 +17,21 @@ | |
package com.linecorp.armeria.server.grpc.kotlin | ||
|
||
import com.linecorp.armeria.common.annotation.UnstableApi | ||
import com.linecorp.armeria.internal.common.kotlin.ArmeriaRequestCoroutineContext | ||
import com.linecorp.armeria.internal.server.grpc.AbstractServerCall | ||
import com.linecorp.armeria.server.grpc.AsyncServerInterceptor | ||
import io.grpc.Context | ||
import io.grpc.Metadata | ||
import io.grpc.ServerCall | ||
import io.grpc.ServerCallHandler | ||
import io.grpc.ServerInterceptor | ||
import kotlinx.coroutines.DelicateCoroutinesApi | ||
import kotlinx.coroutines.GlobalScope | ||
import kotlinx.coroutines.asCoroutineDispatcher | ||
import io.grpc.kotlin.CoroutineContextServerInterceptor | ||
import io.grpc.kotlin.GrpcContextElement | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.future.future | ||
import java.util.concurrent.CompletableFuture | ||
import kotlin.coroutines.CoroutineContext | ||
import kotlin.reflect.full.companionObject | ||
import kotlin.reflect.full.companionObjectInstance | ||
import kotlin.reflect.full.memberProperties | ||
|
||
/** | ||
* A [ServerInterceptor] that is able to suspend the interceptor without blocking the | ||
|
@@ -54,20 +57,19 @@ import java.util.concurrent.CompletableFuture | |
@UnstableApi | ||
interface CoroutineServerInterceptor : AsyncServerInterceptor { | ||
|
||
@OptIn(DelicateCoroutinesApi::class) | ||
override fun <I : Any, O : Any> asyncInterceptCall( | ||
call: ServerCall<I, O>, | ||
headers: Metadata, | ||
next: ServerCallHandler<I, O> | ||
): CompletableFuture<ServerCall.Listener<I>> { | ||
check(call is AbstractServerCall) { | ||
throw IllegalArgumentException( | ||
"Cannot use ${AsyncServerInterceptor::class.java.name} with a non-Armeria gRPC server" | ||
) | ||
} | ||
val executor = call.blockingExecutor() ?: call.eventLoop() | ||
|
||
return GlobalScope.future(executor.asCoroutineDispatcher() + ArmeriaRequestCoroutineContext(call.ctx())) { | ||
// COROUTINE_CONTEXT_KEY.get(): | ||
// It is necessary to propagate the CoroutineContext set by the previous CoroutineContextServerInterceptor. | ||
// (The ArmeriaRequestCoroutineContext is also propagated by CoroutineContextServerInterceptor) | ||
// GrpcContextElement.current(): | ||
// In gRPC-kotlin, the Coroutine Context is propagated using the gRPC Context. | ||
return CoroutineScope( | ||
trustin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
COROUTINE_CONTEXT_KEY.get() + GrpcContextElement.current() | ||
).future { | ||
suspendedInterceptCall(call, headers, next) | ||
} | ||
} | ||
|
@@ -87,4 +89,14 @@ interface CoroutineServerInterceptor : AsyncServerInterceptor { | |
headers: Metadata, | ||
next: ServerCallHandler<ReqT, RespT> | ||
): ServerCall.Listener<ReqT> | ||
|
||
companion object { | ||
@Suppress("UNCHECKED_CAST") | ||
internal val COROUTINE_CONTEXT_KEY: Context.Key<CoroutineContext> = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used reflection... There is no other way.
ikhoon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
CoroutineContextServerInterceptor::class.let { kclass -> | ||
val companionObject = checkNotNull(kclass.companionObject) | ||
val property = companionObject.memberProperties.single { it.name == "COROUTINE_CONTEXT_KEY" } | ||
checkNotNull(property.getter.call(kclass.companionObjectInstance)) as Context.Key<CoroutineContext> | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this assertion is unneeded.