【问题标题】:How do you implement a responding shell script in a Kotlin web service coroutines request?如何在 Kotlin Web 服务协程请求中实现响应 shell 脚本?
【发布时间】:2021-01-07 00:41:24
【问题描述】:

我使用 spring boot 2 和 Kotlin 创建了一个 Web 服务,以通过进程构建器访问特定服务器的相同 unix 脚本和其他程序。响应消息应包含我使用的 shell 脚本的标准输出。但是我对 Kotlin 中的协程有疑问。当我使用 process.waitFor() 这是一个阻塞函数。您如何使用专用线程(-pool)来跟踪外部进程并暂停协同程序? 在下面的代码 sn-p 中,您会看到我如何获取 shell 脚本的返回码及其标准输出信息:

    val process = ProcessBuilder(cmd)
        .redirectErrorStream(true)
        .start()
    val exitCode = process.waitFor()

    return CmdResult(
        exitCode,
        process.inputStream
    )

我在下面的试验中失败了,因为我没有得到标准输出信息,也不知道如何让结果超出范围以将其用作返回类型:

val dispatcher = newFixedThreadPoolContext(4, "myPool")
launch(dispatcher) {
    val process = ProcessBuilder(listOf(cmdScript))
                .redirectErrorStream(true)
                .start()
    val exitCode = process.waitFor()
            
    CmdResult(
        exitCode,
        process.inputStream
    )
}.join()

【问题讨论】:

  • 你可以使用async(dispatcher) { ... },然后调用await()就可以得到结果。 launch 创建的任务更像是一个不返回任何内容的“即发即弃”任务。

标签: kotlin concurrency race-condition kotlin-coroutines processbuilder


【解决方案1】:

您可以使用顶级函数withContext 从协程返回:

val dispatcher = newFixedThreadPoolContext(4, "myPool")

val result = withContext(dispatcher) {
    val process = ProcessBuilder(listOf(cmdScript))
                .redirectErrorStream(true)
                .start()
    val exitCode = process.waitFor()
            
    CmdResult(
        exitCode,
        process.inputStream
    )
}

【讨论】:

  • 最后我什至可以重用我的旧资源,只需围绕 withContext 方法:``` val cmdResult = withContext(Dispatchers.Default) { runCommand(listOf(cmdScript)) } ```
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
相关资源
最近更新 更多