Chr*_*bek 7 ruby asynchronous fibers
使用 Ruby 3.0,asyncgem现在与标准库函数中的阻塞 IO 兼容,我想了解基本功能,但已经被一个简单的示例困惑了:
require 'async'
n = 10
n.times do |i|
Async do
HTTParty.get("https://httpbin.org/delay/1.6")
end
end
Run Code Online (Sandbox Code Playgroud)
这没有表现出任何并行性。查看 Gem 的文档,内容Kernel#async如下:
异步运行任务中给定的代码块,并在必要时创建反应器。
但项目文档似乎澄清了这一点:
在顶层调用时,将创建并运行反应器,并将块作为异步任务调用。将阻塞直到反应堆完成运行。
因此,要使上面的示例起作用:
require 'async'
n = 10
Async do
n.times do |i|
Async do
HTTParty.get("https://httpbin.org/delay/1.6")
end
end
end
Run Code Online (Sandbox Code Playgroud)
这可行,但对读者来说似乎很混乱。作为读者,我们如何知道第一个Async do被阻塞而其他则没有?
因此问题是:宝石的规范基本用法是什么async?
进一步阅读:
如果您的问题是“gem 的基本示例是什么async”,那么您的第二个代码片段就是其中之一。
如果您的问题是“为什么 API 是这样的?”,那么您可能需要询问在其问题板上开发该 gem 的开发人员。
如果您的问题是“如何判断运行Async::Reactor(确实如此Kernel#Async)是否会阻塞,您可以调用Async#Task.current?:
require 'async'
require 'net/http'
def log_whether_blocking
if Async::Task.current?
puts "Async::Task#current? is truthy, calling `Kernel#Async` will not block"
else
puts "Async::Task#current? is falsey, calling `Kernel#Async` will block"
end
end
n = 10
Async do
n.times do |i|
log_whether_blocking
Async do
Net::HTTP.get(URI("https://httpbin.org/delay/1.6"))
end
end
end
n.times do |i|
log_whether_blocking
Async do
Net::HTTP.get(URI("https://httpbin.org/delay/1.6"))
end
end
Run Code Online (Sandbox Code Playgroud)
这给出了输出
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is truthy, calling `Kernel#Async` will not block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Async::Task#current? is falsey, calling `Kernel#Async` will block
Run Code Online (Sandbox Code Playgroud)
虽然对于那些不熟悉 API 的人来说,这可能是一个潜在的枪械,但Async::Reactor如果将其包装在调用中,您始终可以确保同时运行一组 s Kernel#Async,尽管在某些情况下可能没有必要这样做。
| 归档时间: |
|
| 查看次数: |
1571 次 |
| 最近记录: |