使用异步时防止泄漏抽象
我有一个控制器应该运行导入
。导入过程可能需要很长时间,因此我决定使用消息队列
(异步)。我创建了一个 wrapper
接口,它有一个 import
方法来封装实现。从控制器的角度来看,它不应该关心它是如何导入的(无论是直接导入还是异步导入)。但原始代码可能会引发异常,如果它是异步的,则无法在控制器中捕获这些异常。
public function execute()
{
try {
$this->importer->import();
$this->messageManager->addSuccessMessage(__('The import has been successfully performed.'));
} catch (Exception $e) {
$this->logger->error($e->getMessage());
}
我的意思是问题是,如果我将异步导入器与原始导入器交换,我们就可以知道它是成功还是失败。但是,当我们使用异步时,代码不能简单地输出“导入已成功”,也不能输出“导入已安排”,因为这是一种实现细节泄漏。
关于如何解决这个问题有什么建议吗?
更新:我认为这是两个不同的职责:
- 导入
- 安排导入
所以我想它们根本不能互换。
I have a controller that suppose to run the import
. The importing process might take a long time so I have decided to use a message queue
(async). I have created a wrapper
interface that has a method import
to encapsulate the implementation. From the controller's perspective it shouldn't care how it is imported (whether straight away or async). But the original code can throw exceptions and if it is async then there is no way to catch these exceptions in the controller.
public function execute()
{
try {
$this->importer->import();
$this->messageManager->addSuccessMessage(__('The import has been successfully performed.'));
} catch (Exception $e) {
$this->logger->error($e->getMessage());
}
I mean the problem is that if I swap the async importer with the original one, we can know whether it will succeed or fail. But when we use the async one then code can't simply just output "the import has been successful", nor can it output "the import has been scheduled" because it is an implementation detail leak.
Any recommendations on how to solve this problem?
Update: I assume these are two different responsibilities:
- Import
- Schedule the import
So I guess they are not interchangeable at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,经过彻底的思考,我得出的结论是,运行脚本和调度它是两个独立的操作。最初我认为它们应该仅在实现细节的范围上有所不同;我陷入了这个陷阱,因为读取 MQ 的 cron 每分钟都在运行,因此计划脚本的执行似乎几乎立即运行,就像直接运行一样。
因此,有了这个结论,我决定更进一步,将整个事情重命名为“计划操作”而不是“运行操作”。我想用户需要知道它将被调度而不是仅仅运行。如果用户感到困惑并问WTF?为什么它不能直接运行呢?然后有人可能会回答:嗯,由于 A、B 和 C,调度比跑步更好。
So after a thorough thought I have concluded that running the script and scheduling it are two separate actions. Originally I though they should differ only in the scope of implementation detail; I fell into this trap because the cron that is reading that MQ is running every minute so the execution of the scheduled script seems like is running almost instantly, just like it would if it would be run directly.
So with this conclusion I have decided to make a step further and renamed the whole thing into "schedule operation" instead of "run operation". I guess the user needs to know that it is going to be scheduled instead of just run. And if the user is confused and asks WTF? Why cannot it just run instead? Then somebody could answer: well, scheduling is better than running because of A, B and C.