所以我知道这是糟糕的设计,我正在尝试寻找任何不这样做的理由,所以我需要一些帮助。
我有一个正在被命中的 API 端点,需要最多在几秒钟内回复 OK 响应。目前我们正在接受调用并处理大量数据,然后返回 OK,但是,如果 DoLotsOfWork 方法超时,则不会返回 OK 响应。
public IActionResult DoWork([FromBody] MyDTO myDto){
DoLotsOfWork();
return OK()
}
现在我建议我们迁移到某种队列并让作业在那里运行,但我被告知不可以,因为这项工作需要很长时间。相反,我被告知要这样做。
public IActionResult DoWork([FromBody] MyDTO myDto){
try{
return OK();
}
catch{
}
finally{
DoLotsOfWork();
}
}
有人知道这样做有什么缺点吗?
您的方法有两个问题:
这只适用于不返回任何内容的端点。在构建要返回的对象之前,如何返回某些内容?
try
块大概是为了“处理”(剧透警告,你没有处理任何东西)代码中的异常,对吧?好吧,不是 Ok()
调用会抛出异常,而是你的代码,即 finally
中的代码。除非您也将 that 放入 try
中,否则其中的任何异常仍将无法处理,从而打破了我认为首先编写这样的代码的唯一可能原因。
好的,所以主要问题是:
您将告诉发送 API 调用的任何人,响应良好。 如果“DoLotsOfWork”超时,或者抛出任何类型的异常,那么这个小小的繁荣实际上会强制重新启动程序。
try catch 本质上是没有意义的。 您获得的唯一“好处”是您可以在 ok 响应发回后执行“DoLotsOfWork”。
这当然是疯狂的。您告诉任何系统,他们的请求没有达到他们的预期是有原因的。
超时通常需要返回 408 请求超时,因此连接到您的 api 的程序知道,无论它尝试做什么,都不起作用。
然后程序可以再试一次,或者在本地记录它不起作用。 简单地“撒谎”并在完成任何工作之前说“确定”,将会对您的内部日志记录和监控提出惊人的要求,因为您最终必须向调用者报告才能重试,除非您可以解决您这边的超时错误本地。如果该数据太大,或者数据损坏,会导致无限循环。您可能已经告诉连接的客户他们的损坏请求有效。
如果让客户端连接到你的系统,那么我会起诉你,因为你违反了服务协议等。
您应该实施正确的错误处理。 这个黑客是胡说八道,任何说这很好的人都是在对你或他们自己撒谎。
您也可以优化导致超时的任何流程。
但是你在这里所做的,是对连接的客户端撒谎,应该不惜一切代价避免这种情况。