播放框架运行长时间阻塞任务,而不阻塞客户端
Posted
技术标签:
【中文标题】播放框架运行长时间阻塞任务,而不阻塞客户端【英文标题】:Play framework running long blocking tasks, without blocking the client 【发布时间】:2016-04-14 18:25:14 【问题描述】:Web客户端在等待响应时会被阻塞,但服务器上不会阻塞任何东西,服务器资源可以用来服务其他客户端。
某些客户端请求需要我的服务器执行长时间阻塞任务。我知道我可以在单独的线程池中执行它们。 但我也不希望客户端被阻止。我只想立即向客户端返回响应(例如,OK 得到你的厚长阻塞任务)。客户端并不关心获取任务执行的结果,它只需要知道我正在执行它。
如何在游戏中实现这种行为?
我想我可以创建一个作业队列并使用另一个线程来处理作业队列。其中播放控制器仅将作业添加到队列中,而另一个线程从队列中执行作业。我应该这样做吗?我应该使用 Akka 演员吗? (我不知道 Akka 我需要学习它)
【问题讨论】:
【参考方案1】:回调
一切都始于回调。
你肯定看过这个:
Something.save(function(err)
if (err)
//error handling
return;
console.log('success');
);
这是在 javascript 中定义一个回调 - 将异步执行的东西。由于它们的语法、实现等等,回调并不是你真正的朋友。过度使用它们会导致可怕的回调地狱
承诺
在这种情况下:ES6 中的承诺
Something.save()
.then(function()
console.log('success');
)
.catch(function()
//error handling
)
Promise 不是 'ES6 的东西',它们已经存在很多年了,ES6 将它们带给你。 Promise 很好,你甚至可以将它们链接起来:
saveSomething()
.then(updateOtherthing)
.then(deleteStuff)
.then(logResults);
但对于疯狂的人来说,异步已经足够了。
WebSocket
WebSocket 是我推荐的东西:
截至今天very well supported Play 2.x 中的出色支持 全双工 TCP 你终于有时间学习 Akka 了;)因此,您可以创建一个客户端来打开与 Play 应用程序的 WebSocket 连接。在服务器端,您可以handle WebSocket connections either with Akka actors(我推荐)或在流上使用回调。使用actors真的很简单也很有趣——你定义了一个actor——当有人打开一个WebSocket连接时,这个actor的一个实例就会产生,然后你在WebSocket通道中收到的每条消息都会被actor接收到——你可以专注于您的业务逻辑而无需考虑周围环境,然后将消息发送回去 - 这是 Akka 擅长的。
【讨论】:
以上是关于播放框架运行长时间阻塞任务,而不阻塞客户端的主要内容,如果未能解决你的问题,请参考以下文章
python的sched模块可以在任务执行期间不阻塞地运行异步任务吗?
java 多次new DataOutputStream而不关闭,线程阻塞
Javascript Promises库在浏览器中制作“长时间运行代码 - 非阻塞UI”?