使用基于协程的请求处理是否有必要将 Ktor 中的服务和存储库功能标记为挂起?

问题描述 投票:0回答:1

Ktor 中,请求是在 Route 级别与协程异步处理的。考虑到这种架构,将服务和存储库功能标记为suspend是否有必要或有优势?

具体来说,在讨论从 Routes 到存储库并返回的端到端调用流时,考虑到 Ktor 基于协程的请求处理,suspend 函数如何增强性能或设计?本问题重点关注主要由路由调用函数的场景,不包括对服务或存储库的其他类型的调用。

server kotlin-coroutines ktor suspend
1个回答
0
投票

我认为您对协程和挂起函数的作用有误解。将函数标记为

suspend
本身不会改变太多。通过将
suspend
添加到函数中,我们基本上添加了一种技术能力,可以在不阻塞线程的情况下等待某些事情。但如果我们不使用此功能,那么实际上我们不会改变任何东西。

如果您选择常规服务/存储库功能并简单地向其添加

suspend
,而不更改其代码,那么您几乎没有更改任何内容 (1)。这也会令人困惑,因为你说一个函数可以暂停执行,但实际上它不能。另外,如果该函数曾经阻塞线程,那么这真的很糟糕,因为挂起函数应该永远不会阻塞线程。

所以一个简单的答案是:不,我们不应该仅仅因为函数是在协程上下文中执行而将它们标记为

suspend
。如果您不在其中使用协程,即使您的 Route 函数也不需要/不应该被挂起。如果函数的实现确实暂停了执行,我们应该将函数标记为可暂停。潜在可挂起操作的示例包括:等待固定时间、分叉成多个子任务并等待它们、等待另一个协程,例如锁、执行非阻塞 I/O 等。但前提是它们通过挂起而不是阻塞线程来等待。

从另一个角度来看,我们可以说,可挂起函数为其内部代码提供了更多功能,但从外部角度来看,调用起来却比较困难。如果您需要这些附加功能,则需要用

suspend
标记该功能。如果不需要这些功能,一般不应该标记该功能。此外,通过将 Route 函数标记为挂起,您可以轻松有效地从中调用其他挂起函数。

(1) 上面所说的一个例外是客户端框架,它根据签名生成函数的实现。 Room 库就是一个例子。在这种情况下,通过将函数标记为

suspend
,我们实际上更改了其自动生成的实现,因此此类函数真正变得可挂起。

© www.soinside.com 2019 - 2024. All rights reserved.