Kotlin 如何在控制器方法内创建协同程序以调用挂起函数

Kotlin 如何在控制器方法内创建协同程序以调用挂起函数,kotlin,kotlin-coroutines,coroutine,Kotlin,Kotlin Coroutines,Coroutine,目标:我的微服务必须使用另一个Rest端点,我正试图遵循这个目标 下面是我如何在服务中编码以使用另一个rest端点 服务 suspend fun getCoroutine(){ val someData = getData() print(someData) } suspend fun getData(): String { val client = HttpClient.newBuilder() .version(HttpCli

目标:我的微服务必须使用另一个Rest端点,我正试图遵循这个目标

下面是我如何在服务中编码以使用另一个rest端点

服务

suspend fun getCoroutine(){

    val someData = getData()

    print(someData)
}

suspend fun getData(): String {

    
    val client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .authenticator(Authenticator.getDefault())
            .build();

    val request = HttpRequest.newBuilder()
            .uri(URI.create("http://localhost:3000/employees"))
            .build();

    val response = client.sendAsync(request, BodyHandlers.ofString());
    return response.get().body() // suspend and return String not a Future
}
我想从我的控制器调用“suspend-fun-getCoroutine()”方法

package com.tolearn.endpoint

import com.tolearn.DemoGrpcKafkaReply
import com.tolearn.DemoGrpcKafkaRequest
import com.tolearn.DemoGrpcKafkaServiceGrpc
import com.tolearn.service.DemoService
import io.grpc.stub.StreamObserver
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton


@Singleton
class DemoEndpoint : DemoGrpcKafkaServiceGrpc.DemoGrpcKafkaServiceImplBase(){

    @Inject
    lateinit var demoService: DemoService

    override fun send(request: DemoGrpcKafkaRequest?, responseObserver: StreamObserver<DemoGrpcKafkaReply>?) {

        demoService.getCoroutine()

    }
}
主要问题:要从控制器的方法调用挂起函数,我必须做什么?第二个问题,我是否在尝试从控制器方法调用挂起函数?在这种情况下,我利用协同程序是错误的吗

***编辑1

val tryingCoroutine = runBlocking {
    coroutineScope { // Creates a coroutine scope
        launch {
            demoService.getCoroutine()
            println("Task from nested launch")
        }
    }
}
println(tryingCoroutine.isCompleted)

您需要添加
kotlinx coroutines core
依赖项来解析作用域(runBlocking/launch)

以下是maven repo的链接:

范围文档:

一旦将作用域添加到项目中,您应该能够在非挂起块中运行挂起的函数。此外,您还可以使用
CoroutineExceptionHandler
来处理错误。


从技术上讲,控制器应该将任何长时间运行的操作切换到另一个线程,并返回适当的响应。所以你做了一些奇怪的事情。

考虑到我在gradle中的依赖关系,但不幸的是在版本之前有一个拼写错误,我没有得到指向它的错误(实现(“org.jetbrains.kotlinx:kotlinx coroutines core:'1.4.2”)。我阅读了文档并在谷歌上搜索了一下,但我没有学习如何创建作用域。请给出一个简单的例子好吗?我现在可以从我的控制器调用suspend函数了,但是使用了这个非常简单的方法:val tryingCoroutine=runBlocking{demoService.getCoroutine()}。不确定我的方向是否正确。最后,您的最后一个链接基于我创建的上面的作用域(请参见上面的编辑1)。是否正确?它在IntelliJ调试中工作,但我是否在上下文中正确使用了协程作用域(从控制器调用挂起函数)?我应该如何正确处理这里的异常?我是否必须测试它是否已完成?这将帮助您创建自定义范围并处理取消。
override fun send(request: DemoGrpcKafkaRequest?, responseObserver: StreamObserver<DemoGrpcKafkaReply>?) {
    
    launch( demoService.getCoroutine() ) { // not confined -- will work with main thread

    }
plugins {
    id("org.jetbrains.kotlin.jvm") version "1.4.10"
    id("org.jetbrains.kotlin.kapt") version "1.4.10"
    id("org.jetbrains.kotlin.plugin.allopen") version "1.4.10"
    id("com.github.johnrengelman.shadow") version "6.1.0"
    id("io.micronaut.application") version "1.2.0"
    id("com.google.protobuf") version "0.8.13"
}

version = "0.1"
group = "com.tolearn"

repositories {
    mavenLocal()
    jcenter()
    mavenCentral()

}

micronaut {
    testRuntime("junit5")
    processing {
        incremental(true)
        annotations("com.tolearn.*")
    }
}

dependencies {
    implementation("io.micronaut:micronaut-validation")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
    implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
    implementation("io.micronaut:micronaut-runtime")
    implementation("io.micronaut.grpc:micronaut-grpc-runtime")
    implementation("javax.annotation:javax.annotation-api")
    implementation("io.micronaut.kafka:micronaut-kafka")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:'1.4.2")

    runtimeOnly("ch.qos.logback:logback-classic")
    runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
    testImplementation("io.micronaut:micronaut-http-client")
}


application {
    mainClass.set("com.tolearn.ApplicationKt")
}

java {
    sourceCompatibility = JavaVersion.toVersion("11")
}

tasks {
    compileKotlin {
        kotlinOptions {
            jvmTarget = "11"
        }
    }
    compileTestKotlin {
        kotlinOptions {
            jvmTarget = "11"
        }
    }


}

sourceSets {
    main {
        java {
            srcDirs("build/generated/source/proto/main/grpc")
            //srcDirs 'build/generated/source/proto/main/grpckt'
            srcDirs("build/generated/source/proto/main/java")
        }
    }
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.14.0" }
    plugins {
        grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.33.1" }
        //grpckt { artifact = "io.grpc:protoc-gen-grpc-kotlin:1.0.0" }
    }
    generateProtoTasks {
        all()*.plugins {
            grpc {}
            //grpckt {}
        }
    }
}
val tryingCoroutine = runBlocking {
    coroutineScope { // Creates a coroutine scope
        launch {
            demoService.getCoroutine()
            println("Task from nested launch")
        }
    }
}
println(tryingCoroutine.isCompleted)