Thrift 异步函数中的回调?
Posted
技术标签:
【中文标题】Thrift 异步函数中的回调?【英文标题】:Callbacks in Thrift Asynchronous Functions? 【发布时间】:2010-03-31 17:13:08 【问题描述】:在Thrift 中,use the oneway modifier 可以将调用指定为异步。
显然,不可能定义一个回调,以便在函数执行完成时执行。
看来我唯一的可能是给我的 Thrift 客户端(PHP)一些“服务器”功能,这样,当在服务器端完成繁重的计算时,我可以发送通知它。这意味着我应该有一个新的 .thrift 文件,其中包含新定义、新服务和所有其他内容,并且我应该使用 Thrift 生成 php-server 端代码。
即使这是可行的,但对我来说这似乎有点过头了,我想知道是否有更聪明的方法来实现回调。
期待你们的反馈,伙计们。
【问题讨论】:
【参考方案1】:Roberto,不幸的是 Thrift 框架没有这样的内置功能。但是,可能有许多替代方案,这取决于您希望 PHP 客户端会话在您通常等待计算密集型 Thrift 服务器响应的时间段内执行的操作(如果您没有使用oneway
.)
我现在只能想象,如果您编写了一个 Web 应用程序,其中一个用户(或多个并行用户)可以各自触发计算密集型任务,您想提供一些反馈给所述用户,同时所述任务不断进行。
从一开始,您尝试避免您想要避免的解决方案是绝对正确的。您的 PHP 客户端会话无法在不阻塞的情况下为回调接口提供服务(除非您尝试使用 pcntl_fork 或其他一些 PHP threading band-aid 来挖掘更深的漏洞。)
最简单和恕我直言最好的方法是两个从事件驱动模型切换(我希望在服务器完成时收到通知)到轮询模型(我会定期询问服务器是否完成。)实现轮询模型的方法有多种,服务器上也有多种实现选项在客户端,例如:
在调用阶段:
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)
调用计算密集型 Thrift 服务器定期检查计算密集型作业的状态,
-- 或--
在将job_id
传递给浏览器并指示浏览器定期检查计算密集型作业job_id
的状态后,PHP 客户端会话立即终止以释放宝贵的资源(例如,通过META REFRESH
,或通过来自 javascript 的 XHR (AJAX) 请求等);浏览器检查生成一个简短的 PHP 客户端会话,该会话执行 同步 status get_status(job_id)
调用计算密集型 Thrift 服务器,在将状态(无论它可能是什么)转发到浏览器后立即终止李>
【讨论】:
C++ 客户端/服务器似乎也需要这种方法【参考方案2】:我在与 Stack Overflow 不同的频道上收到了答复。由于作者允许我在这里发布他的答案,我认为它可能对社区中的其他人有用。
嘿,罗伯特,
是的,这已经出现在 Apache 之前列出。没有优雅的方式 做你想做的事 节约。这根本不是 专为双向消息传递而设计。
这方面有一些技巧,例如: - 客户端轮询 - 调用 send_method(),在客户端等待,然后是 recv_method(), 而不仅仅是方法() - 让客户端也实现一个 Thrift 服务器
但显然这些都不是真的 双向消息传递。我们试过了 保持 Thrift 接口为 尽可能简单并专注于 核心 RPC 用例,这意味着 留下一些这样的东西。
可能不是你的答案 希望。
干杯,麦克斯利
【讨论】:
【参考方案3】:我没有尝试使用 Thrift 实现回调(我猜这会使协议变得更重),而是使用轻量级消息传递服务 (STOMP - http://stomp.github.com) 来通知客户端异步事件。
我的方法是 Thrift 客户端订阅特定的 STOMP 频道,只要发生异步事件,Thrift 服务器就会在同一频道上发布。然后,客户端可以向服务器查询有关该事件的其他信息。
【讨论】:
【参考方案4】:Java 通过未来对象引用进行异步消息调用。这可以使用Message Pack 在 RPC 模型中实现。我不确定PHP是否有类似的东西。
【讨论】:
以上是关于Thrift 异步函数中的回调?的主要内容,如果未能解决你的问题,请参考以下文章