Je pense tres honnetement que ce procede est mauvais. Tu controlles pas qui lance (et combien) de process. C'est un coup a te retrouver avec plein de process orphelins et a obtenir un deni de service de la part de ton OS.
Le cas d'utilisation est plutot simple ici. T'as une base de donnees qui est updatee regulierement. Dans ce cas la, tu as 2 options tres simples: 1) Tu fais du polling. Toutes les 10 minutes, ton frontend (javascript) fait une requete (ajax) au backend (rails) pour recuperer le nouveau data. 2) tu utilises des websockets (action cable avec rails 5). C'est le serveur qui va pousser les donnees vers le client chaque fois qu'il y en a des nouvelles. Donc ca evite de faire des requetes en boucle vers le serveur. Quand au boutton start stop, dans le premier cas, start demarre le cycle de requetes ajax toutes les 10 minutes (avec setTimeout en vanilla JS). Et le boutton stop detruit cette boucle (clearTimeout en vanilla JS). Dans le second cas, les bouttons start et stop mettent juste a jour un boolean dans les etats de ta vue. Boolean qui sera evalue pour savoir si tu dois ignorer ou non les evenements qui sont pousses par le serveur. Pas besoin de jobs, pas besoin de daemon, pas besoin de boucle infinie cote serveur dans ce cas la. C'est un cas tres classique d'affichage de data "en temps reel". 2016-09-02 18:14 GMT+08:00 Olivier El Mekki <oelme...@gmail.com>: > Hello, > > Dans le cas que tu décris, je partirais sur quelque chose de plus simple > que d'utiliser daemon (qui n'est probablement pas pensé pour être utilisé > avec rails): lancer ton app en commande shell, lui faire stocker son pid > dans un pidfile, puis faire un kill sur le contenu de ce fichier. Voici un > example: > > La partie web: > > ``` > # Ce fichier est en plain ruby, mais l'idée est de reproduire le contenu > # des methodes #start et #stop dans tes controllers > def start > process = spawn( "ruby ./app.rb" ) # tu lances ton process > Process.detach( process ) # tu le détaches de ton process web > end > > def stop > %x(kill $(cat ./app.pid)) if File.exists? "./app.pid" # tu killes ton > process, s'il n'est pas déjà mort > end > > puts "starting" > start > sleep 5 > puts "stopping" > stop > ``` > > Dans ton cas, tu voudras probablement utiliser des path absolus plutôt que > relatifs. > > La partie system: > > ``` > # tu stock le pid de ton process > File.open( "./app.pid", "w" ){ |f| f.puts Process.pid } > > # tu t'assures de supprimer le pidfile quand ton process meurt > Kernel.at_exit do > File.unlink( "./app.pid" ) > end > > > # Code > > sleep 50 # juste pour executer cet example, tu n'en as pas besoin dans ton > code > ``` > > > > On Friday, September 2, 2016 at 11:35:14 AM UTC+2, ziburudebian wrote: >> >> Merci florian pour tes explications, c'est vrai que fournir du code ainsi >> peut paraître complexe, mais au bout d'un moment tout seul dans mon coin à >> coder, je craque... >> tu as raison, j'aurai du commencer par expliquer ce que je veux faire : >> >> sur mon formulaire j'ai 2 boutons START et STOP comme tu l'as compris >> dans mon code; >> le but lorsque je clique sur START est de lancer un programme qui à >> partir d'options choisies sur ma page web, analyse les données dans la base >> et affiche le résultat sur ma page web et le STOP arrête cette analyse; >> les données (que j'analyse) qui alimente ma base sont mises à jour par un >> programme externe toutes les 10 minutes, c'est pour cela que j'ai pensé à >> un boucle infinie qui démarre sur le bouton START >> >> >> Le jeudi 1 septembre 2016 19:14:26 UTC+2, Florian Dutey a écrit : >>> >>> Si tu veux utiliser daemon et rails en meme temps, il faut que tu >>> ecrives dans une queue intermediaire (par exemple redis). Le daemon monitor >>> la queue (boucle infinie), quand ya des nouveaux messages dedans, il les >>> depiles et les traite. Ton controller ne doit jamais inclure la gem daemon >>> et tu ne dois jamais appeler des scrips depuis ton controller, sinon la gem >>> daemon ne sert a rien en fait, tu peux appeler le script directement avec >>> system() et c'est degueulasse. >>> >>> Quand a ton probleme courant, ce qu'on voit dans ton exemple, c'est que >>> tu passes tes ids client en mode "1-2-3-4" depuis le controller et en mode >>> "1 2 3" depuis le shell. >>> >>> Quand au script lui meme, pourquoi lui filer une loop alors que ca sert >>> a rien? C'est pas daemon, c'est un script shell ca >>> C'est aussi plus clean de faire un truc genre >>> Client.find(*client_ids).each { } plutot que client_ids.each { |id| c = >>> Client.find(id) #... } Dans un cas t'as un seul call SQL et dans l'autre, >>> t'as autant de calls que d'ids. >>> >>> Le code de ton daemon est tres confus. On ne demarre pas un daemon >>> depuis un controller. Le daemon doit tourner tout le temps et recevoir des >>> signaux. La tu ne controlles pas combien de daemon seront demarres en >>> parallele. Il suffit de spammer ton serveur pour demarrer des tonnes de >>> daemon et faire peter l'OS qui sera perdu dans les millions de process >>> crees par le serveur. Le fait de stopper quand ton utilisateur veut bien >>> penser a cliquer sur stop (ce qu'il ne fera jamais) me permet de te predire >>> que tu vas devoir redemarrer tes serveurs souvent, et que ton app ne serait >>> jamais disponible. >>> >>> En fait, si tu decrivais ce que tu cherches reellement a faire, ca >>> permettrait probablement de t'aiguiller un peu mieux. Mais la, le code, y'a >>> tellement de fondamentaux qui manquent que personne peut prendre le temps >>> de te donner la solution. >>> >>> 2016-09-01 17:52 GMT+08:00 Philippe Creux <pcr...@gmail.com>: >>> >>>> Bonjour, >>>> >>>> Rails et daemon ne doivent pas faire bon ménage. >>>> >>>> Pour faire tourner des tâches de manière asynchrone dans une >>>> application Ruby on Rails, je te conseille d'utiliser ActiveJob ( >>>> http://guides.rubyonrails.org/active_job_basics.html) et Sidekiq. >>>> >>>> Bon courage! >>>> >>>> -- >>>> φ <http://pcreux.com> >>>> >>>> >>>> 2016-08-31 16:06 GMT+02:00 ziburudebian <devm...@gmail.com>: >>>> >>>>> Bonjour à tous >>>>> >>>>> J'utilise la gem *daemon *mais mon programme ne lit pas toutes les >>>>> données de ma table client : il y a 5 enregistrements, il s'arrête au >>>>> deuxième !!! ça fait trois jours que je cherche, j'en peux plus .... >>>>> Voici mon code : >>>>> >>>>> *runexecution *est la fonction que je lance depuis le bouton de mon >>>>> formulaire; elle est décrite dans >>>>> *app/controllers/executions_controller.rb* >>>>> >>>>> class ExecutionsController < ApplicationController >>>>> >>>>> def runexecution >>>>> # ============================================================ >>>>> ================================================ >>>>> # DESCRIPTION : Permet de demarrer ou arreter l'execution d'un >>>>> script (action=start ou stop) >>>>> # ============================================================ >>>>> ================================================ >>>>> require 'daemons' >>>>> # ---------------------------- >>>>> # traitement des parametres >>>>> # ---------------------------- >>>>> return "" if params.nil? # ce test permet de ne pas rentrer dans >>>>> la fonction lors de l'appel via le menu >>>>> action = "" >>>>> params.each do |key,value| >>>>> action = "start" if (key.index("loopstart") != nil) >>>>> action = "stop" if (key.index("loopstop") != nil) >>>>> end >>>>> logger.info("******************action="+action) >>>>> case action >>>>> when "start" >>>>> exedate = "2015-10-03 08:30" >>>>> frequence = "0.05" >>>>> listclientselectionne = "1-2-3-4-5" >>>>> paramopt = "" >>>>> options = {:ARGV => [action, paramopt, '--', exedate, >>>>> frequence, listclientselectionne], >>>>> :dir_mode => :script, >>>>> :dir => 'tmp/pids', >>>>> :multiple => true, >>>>> :ontop => true, >>>>> :mode => :load, >>>>> :backtrace => true, >>>>> :monitor => true, >>>>> :log_output => true >>>>> } >>>>> logger.info("******************options="+options.to_s) >>>>> Daemons.run('myserver.rb', options) >>>>> logger.info("******************FIN") >>>>> >>>>> when "stop" >>>>> logger.info("******************loopstop") >>>>> else >>>>> redirect_to executions_execution_path >>>>> end # case action >>>>> >>>>> end # runexecution >>>>> >>>>> end #class >>>>> >>>>> le programme qui tourne en boucle est* myserver.rb* qui est à la >>>>> racine de mon site : >>>>> >>>>> #!/usr/bin/env ruby >>>>> ENV['RAILS_ENV'] ||= 'production' >>>>> require File.expand_path('../config/environment', __FILE__) >>>>> print "\nParametres= " + ARGV[0].to_s + "****" + ARGV[1] + "****" + >>>>> ARGV[2] + "\n" >>>>> exedate = ARGV[0] >>>>> frequence = ARGV[1] >>>>> listclientselectionne = ARGV[2] >>>>> delai = frequence.to_f * 60 >>>>> listclientselectionne = listclientselectionne.split("-") >>>>> print "Nbclient=" + listclientselectionne.count.to_s + "\n" >>>>> loop do >>>>> print Time.now.to_s + "\n" >>>>> listclientselectionne.each do |idcl| >>>>> print idcl + "\n" >>>>> begin >>>>> print "avant\n" >>>>> objclient = Client.find(idcl) >>>>> print "apres\n" >>>>> if (!objclient.nil?) >>>>> print objclient.lastname.to_s + "\n" >>>>> # print objclient.name + "\n" >>>>> else >>>>> print "Erreur sur " + idcl + "\n" >>>>> end >>>>> rescue ActiveRecord::RecordNotFound => e >>>>> objclient = nil >>>>> print "Erreur \n" >>>>> end >>>>> end >>>>> sleep(delai) >>>>> end >>>>> >>>>> et voici les résultat à 'écran >>>>> >>>>> => Booting Thin >>>>> => Rails 4.1.7 application starting in production on >>>>> http://0.0.0.0:3000 >>>>> => Run `rails server -h` for more startup options >>>>> => Notice: server is listening on all interfaces (0.0.0.0). Consider >>>>> using 127.0.0.1 (--binding option) >>>>> => Ctrl-C to shutdown server >>>>> Thin web server (v1.6.4 codename Gob Bluth) >>>>> Maximum connections set to 1024 >>>>> Listening on 0.0.0.0:3000, CTRL+C to stop >>>>> myserver.rb: process with pid 28318 started. >>>>> >>>>> Parametres= 2015-10-03 08:30****0.05****5-1-6-2 >>>>> Nbclient=5 >>>>> 2016-08-31 15:47:56 +0200 >>>>> 1 >>>>> avant >>>>> apres >>>>> DURANTON >>>>> 2 >>>>> avant >>>>> apres >>>>> VALENT >>>>> 3 >>>>> avant >>>>> log writing failed. closed stream >>>>> log writing failed. closed stream >>>>> log writing failed. closed stream >>>>> >>>>> >>>>> Si j'exécute le programme *myserver.rb* depuis la console avec *ruby >>>>> myserver.rb 1 2 3 : *tout se passe bien; voici le stdout >>>>> >>>>> # ruby myserver.rb 1 2 3 >>>>> Parametres= 1****2****3 >>>>> Nbclient=5 >>>>> 2016-08-31 16:04:10 +0200 >>>>> 1 >>>>> avant >>>>> apres >>>>> DURANTON888 >>>>> 2 >>>>> avant >>>>> apres >>>>> VALENT >>>>> 3 >>>>> avant >>>>> apres >>>>> VIGILE1AA >>>>> 4 >>>>> avant >>>>> apres >>>>> VIGILE2 >>>>> 5 >>>>> avant >>>>> apres >>>>> DURANDTON >>>>> >>>>> >>>>> >>>>> Si vous avez une idée >>>>> >>>>> Merci beaucoup >>>>> >>>>> *Ma config* >>>>> >>>>> - Debian GNU/Linux 7 >>>>> - Rails 4.17 >>>>> - Ruby 1.91 >>>>> >>>>> -- >>>>> -- >>>>> Vous avez reçu ce message, car vous êtes abonné au groupe >>>>> "Railsfrance" de Google Groups. >>>>> Pour transmettre des messages à ce groupe, envoyez un e-mail à >>>>> l'adresse rails...@googlegroups.com >>>>> Pour résilier votre abonnement envoyez un e-mail à l'adresse >>>>> railsfrance...@googlegroups.com >>>>> --- >>>>> Vous recevez ce message, car vous êtes abonné au groupe Google Groupes >>>>> "Railsfrance". >>>>> Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le >>>>> concernant, envoyez un e-mail à l'adresse >>>>> railsfrance...@googlegroups.com. >>>>> Pour obtenir davantage d'options, consultez la page >>>>> https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>>> -- >>>> Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" >>>> de Google Groups. >>>> Pour transmettre des messages à ce groupe, envoyez un e-mail à >>>> l'adresse rails...@googlegroups.com >>>> Pour résilier votre abonnement envoyez un e-mail à l'adresse >>>> railsfrance...@googlegroups.com >>>> --- >>>> Vous recevez ce message, car vous êtes abonné au groupe Google Groupes >>>> "Railsfrance". >>>> Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le >>>> concernant, envoyez un e-mail à l'adresse >>>> railsfrance...@googlegroups.com. >>>> Pour obtenir davantage d'options, consultez la page >>>> https://groups.google.com/d/optout. >>>> >>> >>> -- > -- > Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de > Google Groups. > Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse > railsfrance@googlegroups.com > Pour résilier votre abonnement envoyez un e-mail à l'adresse > railsfrance-unsubscr...@googlegroups.com > --- > Vous recevez ce message, car vous êtes abonné au groupe Google Groupes > "Railsfrance". > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le > concernant, envoyez un e-mail à l'adresse railsfrance+unsubscribe@ > googlegroups.com. > Pour obtenir davantage d'options, consultez la page > https://groups.google.com/d/optout. > -- -- Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de Google Groups. Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse railsfrance@googlegroups.com Pour résilier votre abonnement envoyez un e-mail à l'adresse railsfrance-unsubscr...@googlegroups.com --- Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Railsfrance. Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse railsfrance+unsubscr...@googlegroups.com. Pour plus d'options, visitez le site https://groups.google.com/d/optout .