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+unsubscr...@googlegroups.com.
Pour plus d'options, visitez le site https://groups.google.com/d/optout .

Répondre à