我需要对Web服务进行API调用才能检索日期。 为此我创建了一个样本以熟悉赛璐珞。 在这里,我将使用openweather API进行“培训”。 最终目标是同时运行多个请求。
我的预订舱位(booking.rb)取数据
require 'celluloid'
require 'open-uri'
require 'json'
class Booking
include Celluloid
def initialize
end
def parse(url)
p "back again"
begin
buffer = open(url).read
p JSON.parse(buffer)['cod']
rescue => e
"fuck"
end
end
end
这就是我运行它的方式:
require 'celluloid'
Celluloid.shutdown_timeout = 10
begin
pool = Booking.pool
%W(
http://api.openweathermap.org/data/2.5/weather?q=London,uk
http://api.openweathermap.org/data/2.5/weather?q=Berlin,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
).each_with_index do |weather, i|
p i
#Booking.new.async.parse(weather)
pool.future.parse(weather)
end
rescue => e
p "ex #{e}"
end
p "start"
现在,当我多次运行时,我会收到不同的错误消息:
ruby run_booking.rb
0
1
2
3
4
5
6
7
8
9
"start"
D, [2015-06-11T21:20:06.351274 #33316] DEBUG -- : Terminating 9 actors...
E, [2015-06-11T21:20:16.356649 #33316] ERROR -- : Couldn't cleanly terminate all actors in 10 seconds!
➜ booking ruby run_booking.rb
0
1
2
3
4
5
6
7
8
9
"start"
D, [2015-06-11T21:22:19.172770 #33344] DEBUG -- : Terminating 9 actors...
W, [2015-06-11T21:22:19.173145 #33344] WARN -- : Terminating task: type=:finalizer, meta={:method_name=>:__shutdown__}, status=:receiving
Celluloid::TaskFiber backtrace unavailable. Please try `Celluloid.task_class = Celluloid::TaskThread` if you need backtraces here.
所以我想知道这里发生了什么?感谢帮助。 提前致谢
答案 0 :(得分:2)
Celluloid
完成工作之前完成。您需要使用#2中显示的方法来避免这种情况。您需要join
每个Future
以确保检索和解析所有信息...否则您只是发起了大量不是block
的异步调用...这意味着什么都没有阻止程序退出。
如果有疑问,只需在程序结束时添加sleep
,直到找到想要优雅完成的方式。到目前为止,您展示的代码不完整。
Celluloid
:在你的Gemfile中:
gem 'celluloid', github: 'celluloid/celluloid', branch: '0.17.0-prerelease', submodules: true
然后当您require
Celluloid
库时,请使用:
require 'celluloid/current'
results = []
booking = Booking.new
%W(
http://api.openweathermap.org/data/2.5/weather?q=London,uk
http://api.openweathermap.org/data/2.5/weather?q=Berlin,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
http://api.openweathermap.org/data/2.5/weather?q=Munich,de
).each_with_index do |weather, i|
p i
results << booking.future.parse(weather)
end
#de Turn the futures into actual results by calling `.value` on each future:
results = results.map(&:value)
http.rb
与Celluloid
支持一起使用:将Celluloid::IO
添加到Gemfile
,如下所示:
gem 'celluloid-io', github: 'celluloid/celluloid-io', branch: '0.17.0-dependent', submodules: true
然后使用HTTP
代替,并传入Celluloid::IO
套接字类型。以下是http.rb
本身的示例:
require "celluloid/io"
require "http"
class HttpFetcher
include Celluloid::IO
def fetch(url)
HTTP.get(url, socket_class: Celluloid::IO::TCPSocket)
end
end
那个电话就在那里使用了公平的TCP,这对你的演员来说非常好,后者有并发的出站聚会电话。