*/ ?>

Démonické procesy v Ruby

Ať už si chceš v Ruby napsat webserver (jako třeba WEBRick), nebo automat na zpracování emailů, budeš potřebovat takzvaný proces na pozadí aneb démon. Démon je jednoduše proces, který nevlastní konzoli. Začněme nejdříve pracovní náplní takového démona. Jediné co následující funkce dělá je, že v nekonečné smyčce jednou za pět vteřin oznámí zápisem do souboru, že stále běží a pokud dojde k ukončení, slušně se rozloučí a soubor zavře.

# main.rb 1
def work(log_file)
  i = 1
  begin
    file = File.open(log_file, "w+")
    loop do
      file.puts "Ti říkam po #{i+=1}té, že nespím!"
      file.flush
      sleep(5)
    end
  ensure
    if file
      file.puts "Já končím."
      file.close
    end
  end
end

Tento kód samozřejmě nic nedělá, je potřeba najít vhodný soubor pro výstup a smyčku spustit.

# main.rb 2
log_file = File.join(File.dirname(__FILE__), "daemon.log")
work(log_file)

Převedení víše uvedeného na démona je díky gemu daemons jednoduché asi takhle:

# main.rb 3
require 'rubygems'
require 'daemons'
Daemons.daemonize

Metoda Daemons.daemonize z aktuálního procesu udělá démona. K tomuto démonovi ale nemáš přístup a jediný způsob ukončení jeho činnosti je, že se ukončí sám (a nebo v horším případě kill). Jiná metoda Daemons.run_proc je daleko zajímavější. Použiješ ji takto:

# main.rb 4
require 'rubygems'
require 'daemons'

LOG_ROOT = File.dirname(File.expand_path(__FILE__))

def work(log_file)
  i = 1
  begin
    file = File.open(log_file, "w+")
    loop do
      file.puts "Ti říkam po #{i+=1}té, že nespím!"
      file.flush
      sleep(5)
    end
  ensure
    if file
      file.puts "Já končím."
      file.close
    end
  end
end

Daemons.run_proc("main.rb.daemon", :log_output => true) do
  log_file = "#{LOG_ROOT}/daemon.log"
  work(log_file)
end

Nejdříve vysvětlím proč jsem změnil cestu k souboru.

LOG_ROOT = File.dirname(File.expand_path(__FILE__))
log_file = "#{LOG_ROOT}/daemon.log"

Démon není stejný proces, jako ten, co jsme spustili z příkazové řádky. Je to samostatný proces, který má jako pracovní adresář nastavený kořen a proto je třeba k výstupnímu souboru zadat absolutní cestu.

Zatímco skripty používající Daemons.daemonize se spouští stejně jako každý jiný Ruby skript,  s Daemons.run_proc dostáváš k dispozici celou řadu kouzel. V okamžiku se z našeho skriptu stal plnohodnotný démon s ovládacím rozhraním.

$ ruby main.rb start # spustí démona na pozadí
$ ruby main.rb status # vypíše jaký je stav
main.rb.daemon: running [pid 9423]
$ ruby main.rb stop # vypne běžící proces
$ ruby main.rb status # vypíše jaký je stav
main.rb.daemon: no instances running

Gem daemons má spoustu dalších zajímavých možností a jak je dobrým zvykem, je velmi dobře dokumentován. Nainstaluješ ho jako každý jiný gem pomocí

gem install daemons

Kód k tomuto článku si můžeš stáhnout na githubu http://github.com/honzasterba/dobrykod/tree/master/demonicke-procesy-v-ruby

  1. Démonické procesy a Rails
  2. Deployment Ruby On Rails jednoduše
  3. Refaktoring iterátoru

Zverejnené 30.10.2008
v kategórii Ruby.

Nálepky:
,

Autor článku

Honza Štěrba, http://honzasterba.cz

Su z Moravy. Pracuju v Sun Microsystems. Programování mě baví.

Vyjadri sa

Tvůj komentář se zobrazí, až ho některý z adminů schválí. Zveřejňovat budeme pouze hodnotné komentáře, které se přímo týkají tématu.


O projekte

Tento projekt vznikol, pretože všetky odborné weby sajú a my sme tým pádom nemali kde publikovať svoje články.