SIdekiq 不执行异步(Sinatra 和 Rack)
SIdekiq doesn't perform async (Sinatra & Rack)
我真的是Ruby的新手。我懂这门语言,但我真的很难找到正确的项目结构方式,有很多文章和教程建议 运行 不要使用简单的 ruby
命令,而是例如 rackup
.如果我的应用程序使用多个 gem,我无法使用其他命令,它们被用作包装器?
至于我的项目。我正在使用 Sinatra
和 Rack & Sidekiq
创建简单的 API,我按如下方式启动我的应用程序。
rackup -p1600 --host 192.168.0.130 config.ru
但我刚开始使用 sidekiq
并且它需要 Redis server
我已经安装了它,现在一切正常,没有错误。
但问题是我的任务没有被处理。
这是我的例子
我的端点
post '/items' do
item_url = params[:item_url]
halt(400, {error: 'Item url is not provided'}.to_json) if item_url.nil?
begin
item_handler = ItemHandler.new item_url
item_handler.start_processing
item_handler.item_status.to_json
rescue APIErrors::AlreadyExistsError => e
halt(409, {error: e.message}.to_json)
rescue APIErrors::InvalidPayloadError => e
halt(400, {error: e.message}.to_json)
end
end
还有我的ItemHandler
Sidekiq.configure_server do |config|
config.redis = {password: 'password'}
end
Sidekiq.configure_client do |config|
config.redis = {password: 'password'}
end
class ItemHandler
...
...
...
def start_processing
ItemWorker.perform_async(@item.id)
end
最后 ItemWorker
require 'sidekiq'
class ItemWorker
include Sidekiq::Worker
attr_accessor :item
def perform(id)
# Get item model
@item = ItemModel.where(_id: id)
logger.info "Doing hard work"
puts @item.status
# Start item processing
process_item
end
def process_item
logger.info "Doing hard work"
puts 'Start processing'
@item.status = ItemModel::STATUS[:downloading]
@item.save
result = download_item_file
if result > RESULT_OK
@item.status = ItemModel::STATUS[:failed_download]
@item.save
puts 'Failed to download file'
else
puts 'File downloaded'
@item.status = ItemModel::STATUS[:downloaded]
@item.save
end
end
def download_item_file
return if @item.nil?
dl_command = EXTERNAL_DOWNLOAD.dup
dl_command['|url|'] = @item.url
system dl_command
$?.exitstatus
end
end
什么也没有发生,控制台没有输出,什么也没有。以前我使用 fork
而不是 sidekiq
并且效果很好。
请帮我找出问题。
P.S。如果我以错误的方式做其他事情(不遵循最佳实践和指南),请告诉我。
感谢大家的帮助,我刚刚意识到一件重要的事情,要使 sidekiq
工作,首先应该启动它:))
所以我只是使用这个命令来启动 'sidekiq' 现在它工作正常。
sidekiq -r ./item_downloader.rb
我的错
这是一个使用 sidekiq/redis
和 sinatra
的完整示例应用程序:
~/sinatra_projects$ tree myapp/
myapp/
├── config.ru
├── item_handler.rb
├── item_worker.rb
└── sinatra_app.rb
sinatra_app.rb:
require 'sinatra'
require_relative 'item_handler' #=>look for item_handler.rb in the same directory as this file
get '/' do
"hello world"
end
post '/item' do
puts "--->#{params[:item_url]}<---"
item_handler = ItemHandler.new params[:item_url]
item_handler.start_processing
"Thanks for the work\n"
end
item_handler.rb:
require_relative 'item_worker' #look for item_worker.rb in the same directory as this file
class ItemHandler
def initialize(url)
@url = url
end
def start_processing
ItemWorker.perform_async @url
end
end
item_worker.rb:
require 'sidekiq'
Sidekiq.configure_server do |config|
#Not much documentation on what you can/should do in here
end
Sidekiq.configure_client do |config|
#Not much documentation on what you can/should do in here
end
class ItemWorker
include Sidekiq::Worker
def perform(url)
logger.info "Things are happening"
case url
when /joe_blow.com/
sleep 5
logger.info "joe_blow.com took a really long time"
when /twitter_clone.com/
sleep 3
logger.info "twitter_clone.com was pretty slow"
else /google.com/
sleep 1
logger.info "google.com response was the quickest"
end
end
end
config.ru:
require_relative 'sinatra_app' #=>look for sinatra_app.rb in the same directory as this file
run Sinatra::Application
整理一下 运行ning:
1) Download 并安装redis(与redis不同gem),然后在terminal_window1启动redis:
$ ~/Downloads/redis-3.2.6/src$ ./redis-server
2) 安装 sidekiq gem
(这也会安装 redis gem
,因为它是一个依赖项):
$ gem install sidekiq
3) 在terminal_window2开始sidekiq:
~/sinatra_projects/myproj$ sidekiq -r ./item_worker.rb
4) 在 terminal_window3 中启动 Sinatra 应用程序:
~/sinatra_projects/myproj$ rackup config.ru
5) 在 terminal_window4 中向您的应用发送 post 请求:
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
curl window 将立即显示输出:
Thanks for the work
sidekiq window 将显示输出:
2016-12-28T02:34:59.149Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: start
2016-12-28T02:34:59.149Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: Things are happening
五秒后,sidekiq window 会显示:
2016-12-28T02:35:04.153Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: joe_blow.com took a really long time
2016-12-28T02:35:04.154Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: done: 5.004 sec
并且如果您快速连续发送三个 curl 请求(up_arrow + Return):
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
然后在sideqik window你会看到:
2016-12-28T02:38:01.218Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: start
2016-12-28T02:38:01.218Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: Things are happening
2016-12-28T02:38:01.983Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: start
2016-12-28T02:38:01.983Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: Things are happening
2016-12-28T02:38:02.602Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: start
2016-12-28T02:38:02.602Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: Things are happening
...时间流逝...
2016-12-28T02:38:06.220Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: joe_blow.com took a really long time
2016-12-28T02:38:06.220Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: done: 5.003 sec
2016-12-28T02:38:06.985Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: joe_blow.com took a really long time
2016-12-28T02:38:06.985Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: done: 5.002 sec
2016-12-28T02:38:07.603Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: joe_blow.com took a really long time
2016-12-28T02:38:07.603Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: done: 5.001 sec
所有三个工人 运行 总共需要 15 秒,而不是 5 秒后所有三个工人都完成了。
我真的是Ruby的新手。我懂这门语言,但我真的很难找到正确的项目结构方式,有很多文章和教程建议 运行 不要使用简单的 ruby
命令,而是例如 rackup
.如果我的应用程序使用多个 gem,我无法使用其他命令,它们被用作包装器?
至于我的项目。我正在使用 Sinatra
和 Rack & Sidekiq
创建简单的 API,我按如下方式启动我的应用程序。
rackup -p1600 --host 192.168.0.130 config.ru
但我刚开始使用 sidekiq
并且它需要 Redis server
我已经安装了它,现在一切正常,没有错误。
但问题是我的任务没有被处理。
这是我的例子
我的端点
post '/items' do
item_url = params[:item_url]
halt(400, {error: 'Item url is not provided'}.to_json) if item_url.nil?
begin
item_handler = ItemHandler.new item_url
item_handler.start_processing
item_handler.item_status.to_json
rescue APIErrors::AlreadyExistsError => e
halt(409, {error: e.message}.to_json)
rescue APIErrors::InvalidPayloadError => e
halt(400, {error: e.message}.to_json)
end
end
还有我的ItemHandler
Sidekiq.configure_server do |config|
config.redis = {password: 'password'}
end
Sidekiq.configure_client do |config|
config.redis = {password: 'password'}
end
class ItemHandler
...
...
...
def start_processing
ItemWorker.perform_async(@item.id)
end
最后 ItemWorker
require 'sidekiq'
class ItemWorker
include Sidekiq::Worker
attr_accessor :item
def perform(id)
# Get item model
@item = ItemModel.where(_id: id)
logger.info "Doing hard work"
puts @item.status
# Start item processing
process_item
end
def process_item
logger.info "Doing hard work"
puts 'Start processing'
@item.status = ItemModel::STATUS[:downloading]
@item.save
result = download_item_file
if result > RESULT_OK
@item.status = ItemModel::STATUS[:failed_download]
@item.save
puts 'Failed to download file'
else
puts 'File downloaded'
@item.status = ItemModel::STATUS[:downloaded]
@item.save
end
end
def download_item_file
return if @item.nil?
dl_command = EXTERNAL_DOWNLOAD.dup
dl_command['|url|'] = @item.url
system dl_command
$?.exitstatus
end
end
什么也没有发生,控制台没有输出,什么也没有。以前我使用 fork
而不是 sidekiq
并且效果很好。
请帮我找出问题。
P.S。如果我以错误的方式做其他事情(不遵循最佳实践和指南),请告诉我。
感谢大家的帮助,我刚刚意识到一件重要的事情,要使 sidekiq
工作,首先应该启动它:))
所以我只是使用这个命令来启动 'sidekiq' 现在它工作正常。
sidekiq -r ./item_downloader.rb
我的错
这是一个使用 sidekiq/redis
和 sinatra
的完整示例应用程序:
~/sinatra_projects$ tree myapp/
myapp/
├── config.ru
├── item_handler.rb
├── item_worker.rb
└── sinatra_app.rb
sinatra_app.rb:
require 'sinatra'
require_relative 'item_handler' #=>look for item_handler.rb in the same directory as this file
get '/' do
"hello world"
end
post '/item' do
puts "--->#{params[:item_url]}<---"
item_handler = ItemHandler.new params[:item_url]
item_handler.start_processing
"Thanks for the work\n"
end
item_handler.rb:
require_relative 'item_worker' #look for item_worker.rb in the same directory as this file
class ItemHandler
def initialize(url)
@url = url
end
def start_processing
ItemWorker.perform_async @url
end
end
item_worker.rb:
require 'sidekiq'
Sidekiq.configure_server do |config|
#Not much documentation on what you can/should do in here
end
Sidekiq.configure_client do |config|
#Not much documentation on what you can/should do in here
end
class ItemWorker
include Sidekiq::Worker
def perform(url)
logger.info "Things are happening"
case url
when /joe_blow.com/
sleep 5
logger.info "joe_blow.com took a really long time"
when /twitter_clone.com/
sleep 3
logger.info "twitter_clone.com was pretty slow"
else /google.com/
sleep 1
logger.info "google.com response was the quickest"
end
end
end
config.ru:
require_relative 'sinatra_app' #=>look for sinatra_app.rb in the same directory as this file
run Sinatra::Application
整理一下 运行ning:
1) Download 并安装redis(与redis不同gem),然后在terminal_window1启动redis:
$ ~/Downloads/redis-3.2.6/src$ ./redis-server
2) 安装 sidekiq gem
(这也会安装 redis gem
,因为它是一个依赖项):
$ gem install sidekiq
3) 在terminal_window2开始sidekiq:
~/sinatra_projects/myproj$ sidekiq -r ./item_worker.rb
4) 在 terminal_window3 中启动 Sinatra 应用程序:
~/sinatra_projects/myproj$ rackup config.ru
5) 在 terminal_window4 中向您的应用发送 post 请求:
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
curl window 将立即显示输出:
Thanks for the work
sidekiq window 将显示输出:
2016-12-28T02:34:59.149Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: start
2016-12-28T02:34:59.149Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: Things are happening
五秒后,sidekiq window 会显示:
2016-12-28T02:35:04.153Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: joe_blow.com took a really long time
2016-12-28T02:35:04.154Z 12387 TID-oxt2yycrk ItemWorker JID-b9190f121541d82f21483497 INFO: done: 5.004 sec
并且如果您快速连续发送三个 curl 请求(up_arrow + Return):
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item
Thanks for the work
然后在sideqik window你会看到:
2016-12-28T02:38:01.218Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: start
2016-12-28T02:38:01.218Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: Things are happening
2016-12-28T02:38:01.983Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: start
2016-12-28T02:38:01.983Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: Things are happening
2016-12-28T02:38:02.602Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: start
2016-12-28T02:38:02.602Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: Things are happening
...时间流逝...
2016-12-28T02:38:06.220Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: joe_blow.com took a really long time
2016-12-28T02:38:06.220Z 12387 TID-oxt2yycrk ItemWorker JID-3c8db3dc597789eefaf3d7e6 INFO: done: 5.003 sec
2016-12-28T02:38:06.985Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: joe_blow.com took a really long time
2016-12-28T02:38:06.985Z 12387 TID-oxt319uyc ItemWorker JID-d5a4f4fa5388b2fdb94b8549 INFO: done: 5.002 sec
2016-12-28T02:38:07.603Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: joe_blow.com took a really long time
2016-12-28T02:38:07.603Z 12387 TID-oxt2y8eec ItemWorker JID-dd8b2ce2e558f5a88a1836fa INFO: done: 5.001 sec
所有三个工人 运行 总共需要 15 秒,而不是 5 秒后所有三个工人都完成了。