Thrift异步函数中的回调?

21
Thrift中,可以使用oneway修饰符指定调用为异步
然而,似乎不可能定义一个回调函数在函数执行完成时被执行。
看起来我唯一的选择是赋予我的Thrift客户端(PHP)一些“服务器”功能,以便当服务器端完成繁重的计算时,我可以向其发送通知。这意味着我应该有一个新的.thrift文件,有新的定义、新的服务和所有其他内容,我应该使用Thrift生成php-server端代码。
即使这是可行的,对我来说似乎过度了,我想知道是否有更聪明的方法来实现回调。
期待得到你们的一些反馈。
4个回答

19
很抱歉,Roberto,Thrift框架没有这样的内置功能。然而,根据你希望在等待计算密集型Thrift服务器回答的时间内,你想让PHP客户端会话做些什么,可能有许多替代方案。
我只能想象,目前你的情况是,在编写一个Web应用程序时,用户(或多个用户并行)可以触发计算密集型任务,同时你想在这些任务执行过程中为用户提供一些反馈。
从一开始,你试图避免的解决方案是完全正确的。除非你深入挖掘并尝试使用pcntl_fork或其他PHP线程绷带,否则你的PHP客户端会话无法服务于回调接口而不阻塞。
最简单且我认为最好的方法是从事件驱动模型切换到轮询模型(“我将定期查询服务器是否完成”)。实现轮询模型有几种方法,服务器和客户端都有多种实现选项,例如:
调用阶段期间:
PHP客户端会分配一个唯一的job_id值,然后向计算密集型Thrift服务器进行异步的oneway调用void compute(..., job_id)-- 或者 -- PHP客户端会向计算密集型Thrift服务器进行同步调用job_id start_compute(...),服务器会分配唯一的job_id值,然后在单独的线程/进程中启动实际的计算密集型任务,并立即返回带有分配的job_id的响应给PHP客户端。
计算阶段期间:
PHP客户端会定期通过同步的status get_status(job_id)调用来检查计算密集型作业的状态。 -- 或者 -- PHP客户端会立即终止以释放宝贵的资源,将job_id传递给浏览器并指示浏览器定期检查计算密集型作业job_id的状态(例如通过META REFRESH或通过Javascript的XHR(AJAX)请求等)。浏览器检查会生成一个简短的PHP客户端会话,执行同步的status get_status(job_id)调用到计算密集型Thrift服务器,立即在将状态(无论哪种)转发给浏览器后终止。

2
这种方法似乎对于C++客户端/服务器也是必要的。 - Ghita

8

我在Stack Overflow以外的渠道收到了一份答案。由于作者给了我在这里发布他的答案的许可,我认为这可能对社区中的其他人有用。

嘿,Robert,

是的,这在Apache列表中曾经被提出过。使用Thrift没有优雅的方法来实现您所要求的双向消息传递。

有一些解决方案,例如:

  • 客户端轮询
  • 调用send_method(),在客户端等待,然后recv_method(),而不仅仅是method()
  • 使客户端也实现Thrift服务器

但很明显,这些都不是真正的双向消息传递。我们试图将Thrift接口保持尽可能简单,并专注于核心RPC用例,这意味着留下了一些类似于这样的东西。

可能不是你希望得到的答案。

干杯,mcslee


3

我采用了轻量级的消息服务(STOMP - http://stomp.github.com)来通知客户端异步事件,而不是尝试使用Thrift实现回调(这可能会使协议变得更重)。

我的方法是,Thrift客户端订阅特定的STOMP频道,当发生异步事件时,Thrift服务器将在同一频道上发布。然后客户端可以查询服务器以获取有关事件的其他信息。


0

Java有通过Future对象引用进行异步消息调用的功能。这可以在使用Message Pack的RPC模型中实现。我不确定PHP是否有类似的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接