为什么使用赛璐珞会出现随机错误?
Why do I get random errors by using celluloid?
我需要对网络服务进行 API 次调用才能检索日期。
为此,我创建了一个样本以熟悉赛璐珞。
在这里,我将使用 openweather API 用于 "training" 目的。
最终目标是 运行 并发多个请求。
我的预订class (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。您的程序在 Celluloid
开始工作之前完成。
您需要使用#2 中所示的方法来避免这种情况。您需要 join
每个 Future
以确保检索和解析所有信息...否则您只是触发了大量不 block
的异步调用...这意味着没有什么能阻止程序退出。
如有疑问,只需将 sleep
添加到程序末尾,直到您弄清楚要如何优雅地完成。到目前为止,您显示的代码是不完整的。
1。像这样使用新版本 Celluloid
:
在你的 Gemfile 中:
gem 'celluloid', github: 'celluloid/celluloid', branch: '0.17.0-prerelease', submodules: true
然后当你 require
Celluloid
库时,使用这个:
require 'celluloid/current'
2。只需使用期货。你根本不需要游泳池,它会减慢你的速度:
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)
3。在 Celluloid
支持下使用 http.rb
:
像这样将 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,这非常适合具有并发出站收集调用的 actor。
我需要对网络服务进行 API 次调用才能检索日期。 为此,我创建了一个样本以熟悉赛璐珞。 在这里,我将使用 openweather API 用于 "training" 目的。 最终目标是 运行 并发多个请求。
我的预订class (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。您的程序在 Celluloid
开始工作之前完成。
您需要使用#2 中所示的方法来避免这种情况。您需要 join
每个 Future
以确保检索和解析所有信息...否则您只是触发了大量不 block
的异步调用...这意味着没有什么能阻止程序退出。
如有疑问,只需将 sleep
添加到程序末尾,直到您弄清楚要如何优雅地完成。到目前为止,您显示的代码是不完整的。
1。像这样使用新版本 Celluloid
:
在你的 Gemfile 中:
gem 'celluloid', github: 'celluloid/celluloid', branch: '0.17.0-prerelease', submodules: true
然后当你 require
Celluloid
库时,使用这个:
require 'celluloid/current'
2。只需使用期货。你根本不需要游泳池,它会减慢你的速度:
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)
3。在 Celluloid
支持下使用 http.rb
:
像这样将 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,这非常适合具有并发出站收集调用的 actor。