【发布时间】:2015-11-10 01:18:47
【问题描述】:
Spray HTTP 服务器的示例使用似乎使服务器按顺序而不是同时处理请求变得非常容易。这是正确的,因为示例显示路由对象实现为一次处理一个请求的参与者(facepalm?**)。这个seems 到be a 普通problem。
例如,在下面,访问 /work1 异步处理请求,但不幸的是,对于 /work2,我们阻止了所有其他请求(假设 /work2 需要忙于从数据库中的 cookie 验证令牌)。
有没有办法使用 spray.routing 在执行分叉之前到达路由?
import akka.actor.ActorSystem
import spray.http.{MediaTypes, HttpEntity}
import spray.routing.SimpleRoutingApp
import scala.concurrent.Future
class MySimpleServer(val system: ActorSystem, val HOST: String, val PORT: Int) extends SimpleRoutingApp {
implicit val _system: ActorSystem = system
import _system.dispatcher
def main(args: Array[String]): Unit = {
startServer(interface = HOST, port = PORT) {
get {
path("work1") {
complete {
// Asynchronously process some work
Future.apply {
Thread.sleep(1000)
HttpEntity(
MediaTypes.`text/html`,
"OK"
)
}
}
} ~
path("work2") {
complete {
// Synchronously process some work and block all routing for this Actor.
// Oh sh*t!
Thread.sleep(1000)
HttpEntity(
MediaTypes.`text/html`,
"OK"
)
}
}
}
}
}
}
** 由于路由通常是无状态操作,因此制作路由器和 Actor 似乎没有什么好处,对吧?
对于我使用过的所有其他网络服务器,在接受 TCP 连接后几乎立即发生对处理程序进程或线程(IMO)的连接的控制。 (我认为)这可以最大限度地提高接收连接的速率,并将无意阻塞的风险降至最低——至少,完全避免路由中的无意阻塞。
更新:
正如@rahilb 建议的那样
detach() {
get {...} ..
}
并调用为:
val responses = (0 until 10)
.map { _ => (IO(Http) ? HttpRequest(GET, s"${TEST_BASE_URL}work1")).mapTo[HttpResponse] }
.map { response => Await.result(response, 5 seconds) }
... work1 或 work2 仍然需要大约 3 秒。
【问题讨论】:
标签: scala spray spray-routing