2016-12-26 1 views
0

Je suis vraiment novice à Ruby. Je comprends la langue, mais il est vraiment difficile pour moi d'obtenir la bonne façon de structurer le projet, il y a beaucoup d'articles et de tutoriels qui suggèrent de ne pas exécuter avec la simple commande ruby mais par exemple rackup. Je ne peux pas avoir une idée de l'utilisation d'autres commandes si mon application utilisant plusieurs gemmes, il est utilisé comme un wrapper?SIdekiq n'effectue pas d'async (Sinatra & Rack)

Comme pour mon projet. Je crée une API simple avec Sinatra & Rack & Sidekiq, je commence mon application comme suit.

rackup -p1600 --host 192.168.0.130 config.ru 

Mais je viens de commencer à utiliser sidekiq et il a fallu que je l'ai installé Redis server, maintenant tout fonctionne sans erreur.

Mais le problème est que ma tâche n'est pas en cours de traitement.

Voici mon exemple

Mon point final

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 

Et mon 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 

Et finnally 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 

Et rien arrive, pas de sortie dans la console, rien. Auparavant, j'ai utilisé fork au lieu de sidekiq et cela a bien fonctionné.

S'il vous plaît aidez-moi à trouver le problème.

P.S. Si je fais quelque chose d'autre dans un mauvais sens (ne suivez pas les bonnes pratiques & directives) s'il vous plaît faites le moi savoir.

+1

Cela ne fonctionne toujours pas? tout semble bien, pouvez-vous sûr avec nous les journaux après le déclenchement de la fonction? – amrdruid

Répondre

1

Voici une application complète en utilisant par exemple sidekiq/redis et 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 

Pour obtenir les choses et le fonctionnement:

1) Download et installer Redis (pas les mêmes que la gemme Redis), puis en terminal_window1 début Redis:

$ ~/Downloads/redis-3.2.6/src$ ./redis-server 

2) Installez le sidekiq gem (qui va également installer le redis gem car c'est une dépendance):

$ gem install sidekiq 

3) Lancer sidekiq en terminal_window2:

~/sinatra_projects/myproj$ sidekiq -r ./item_worker.rb 

4) Lancez l'application Sinatra dans terminal_window3:

~/sinatra_projects/myproj$ rackup config.ru 

5) Envoyer une demande de poste à votre application dans terminal_window4:

$ curl --data "item_url=http://joe_blow.com" http://localhost:9292/item 

Immédiatement, la fenêtre curl affichera la sortie:

Thanks for the work 

et la fenêtre sidekiq affiche la sortie:

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 

Cinq secondes plus tard, la fenêtre sidekiq affiche:

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 

Et si vous envoyez trois demandes papillotes en succession rapide (up_arrow + Retour):

$ 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 

puis dans la fenêtre sideqik vous verrez:

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 

... le temps passe ...

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 

Au lieu de prendre un total de 15 secondes pour exécuter les trois travailleurs, au bout de 5 secondes les trois travailleurs ont terminé.

1

Merci à tous de l'aide, je venez de réaliser une chose importante, pour faire sidekiq travail, d'une part, il doit être démarré :))

Alors je viens d'utiliser cette commande pour démarrer « sidekiq » et il fonctionne très bien maintenant .

sidekiq -r ./item_downloader.rb 

Mon mauvais

+1

Merci de l'avoir posté. J'ai créé une application plus simple à partir de votre exemple, et je n'ai pu voir aucun message de journal non plus. Je me suis cogné la tête contre un mur pendant une journée. Il n'est pas clair à partir de votre message quel fichier vous êtes supposé spécifier dans la commande 'sidekiq' - j'ai spécifié le fichier qui contient la classe qui a la ligne' include Sidekiq: Worker' à l'intérieur, par exemple. item_worker.rb. Ensuite, dans la fenêtre du terminal où j'ai émis la commande sideqik (v. La fenêtre où j'ai émis la commande rackup ou la fenêtre où j'ai démarré redis), j'ai pu voir les messages enregistrés. – 7stud