在异步作业中使用 sleep 是否合理?
Is it a reasonable trade-off to use `sleep` in an asynchronous job?
假设我有一个场景,我正在处理一个工作人员的后台作业。它只是接收远程 CDN 上托管的文件(图像、视频、pdf、..)的 URL,工作人员的工作方式如下:
- 对内存中文件内容的一些处理
- 然后调用第 3 方 API 检索 a signed valid URL 以将内容上传到同一个第 3 方。
- 将内容上传到第 3 方API – 响应包含一个唯一的文件 ID
- Sends a message to a user 通过第 3 方 API 使用之前收到的唯一文件 ID
现在,问题在步骤(3)和(4)之间。这里的约束是第 3 方 API 在我们实际发送包含我们刚刚上传的文件 ID 的消息(第 4 步)之前需要几秒钟来处理文件(第 3 步)。
这里的另一个假设是,我需要确保所有 4 个步骤一次执行,没有任何部分失败的机会。
可能的方法
最天真的方法是在步骤 (3) 和 (4) 之间使用 sleep 5
,这可能会造成伤害/严重失败,因为我不确定需要多少秒3rd方API需要处理,但根据我的试验,5秒睡眠似乎还可以。
我可以对步骤 (3) 进行 3(或 X)次进程内指数重试,捕获来自第 3 方的异常并尝试执行步骤 (4) 当步骤 ( 3) 成功 – 这就是我现在拥有的,它工作正常。
我或许可以使用作业调度程序或 ruby 并发库以延迟方式执行步骤 (4)。我不喜欢这条路,因为它感觉它有利于复杂性。
这段逻辑是内置在 Ruby 中的,虽然问题可能不是很 Ruby 具体并且可以适用于其他语言,但我想听听 Ruby人们认为。
你链接的API docs说:
Attention! Some time needed by a server to process an uploaded file.
File should be sent to a chat after a short timeout (a couple of
seconds)
我通常会反对这种性质的东西,但由于您的供应商特别说明 "timeout",sleep
是最佳选择。
我会尝试执行延迟任务,因为它允许线程继续工作(因此线程池不需要创建新线程(从内存方面来说它们非常昂贵),您的线程可能会继续做有用的工作不需要上下文切换(从 CPU 使用方面来说是昂贵的),...)。
至于解决方案的纯度,异步编程不应该涉及任何阻塞任务(我们实际上是在使用异步编程来对抗阻塞),所以这是使用延迟任务的另一个原因。
如果应用程序不涉及实现最高性能(Ruby 面向性能的语言吗?),那么睡眠可能真的是最简单的,但不是最佳解决方案。
假设我有一个场景,我正在处理一个工作人员的后台作业。它只是接收远程 CDN 上托管的文件(图像、视频、pdf、..)的 URL,工作人员的工作方式如下:
- 对内存中文件内容的一些处理
- 然后调用第 3 方 API 检索 a signed valid URL 以将内容上传到同一个第 3 方。
- 将内容上传到第 3 方API – 响应包含一个唯一的文件 ID
- Sends a message to a user 通过第 3 方 API 使用之前收到的唯一文件 ID
现在,问题在步骤(3)和(4)之间。这里的约束是第 3 方 API 在我们实际发送包含我们刚刚上传的文件 ID 的消息(第 4 步)之前需要几秒钟来处理文件(第 3 步)。
这里的另一个假设是,我需要确保所有 4 个步骤一次执行,没有任何部分失败的机会。
可能的方法
最天真的方法是在步骤 (3) 和 (4) 之间使用
sleep 5
,这可能会造成伤害/严重失败,因为我不确定需要多少秒3rd方API需要处理,但根据我的试验,5秒睡眠似乎还可以。我可以对步骤 (3) 进行 3(或 X)次进程内指数重试,捕获来自第 3 方的异常并尝试执行步骤 (4) 当步骤 ( 3) 成功 – 这就是我现在拥有的,它工作正常。
我或许可以使用作业调度程序或 ruby 并发库以延迟方式执行步骤 (4)。我不喜欢这条路,因为它感觉它有利于复杂性。
这段逻辑是内置在 Ruby 中的,虽然问题可能不是很 Ruby 具体并且可以适用于其他语言,但我想听听 Ruby人们认为。
你链接的API docs说:
Attention! Some time needed by a server to process an uploaded file. File should be sent to a chat after a short timeout (a couple of seconds)
我通常会反对这种性质的东西,但由于您的供应商特别说明 "timeout",sleep
是最佳选择。
我会尝试执行延迟任务,因为它允许线程继续工作(因此线程池不需要创建新线程(从内存方面来说它们非常昂贵),您的线程可能会继续做有用的工作不需要上下文切换(从 CPU 使用方面来说是昂贵的),...)。
至于解决方案的纯度,异步编程不应该涉及任何阻塞任务(我们实际上是在使用异步编程来对抗阻塞),所以这是使用延迟任务的另一个原因。
如果应用程序不涉及实现最高性能(Ruby 面向性能的语言吗?),那么睡眠可能真的是最简单的,但不是最佳解决方案。