Background Jobs - Com BackgrounDRb
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Background Jobs - Com BackgrounDRb

on

  • 2,159 views

 

Statistics

Views

Total Views
2,159
Views on SlideShare
2,052
Embed Views
107

Actions

Likes
0
Downloads
4
Comments
0

3 Embeds 107

http://blog.softa.com.br 95
http://flavors.me 8
http://www.slideshare.net 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Background Jobs - Com BackgrounDRb Presentation Transcript

  • 1. Background Jobs com BackgrounDRb da série "Palestras na Softa" blog.softa.com.br Recomende: workingwithrails.com/person/9354
  • 2. BackgrounDRb BackgrounDRb é um agendador e servidor de tarefas em Ruby. Seu objetivo principal é ser utilizado com aplicações Ruby on Rails - plugin - para desafogar tarefas de longa duração. É feito com PACKET e não DRb. Mas pra entender o conceito, vamos lá...
  • 3. DRb Isso é um "tipo" de digressão. DRb é o Distributed Ruby. Sim, um CORBA simplificado do Ruby. Serialização de objetos sobre TCP. DRb em Ruby é Standard Library. http://ruby-doc.org/stdlib/libdoc/drb/rdoc/index.html
  • 4. Hello DRb World Clone: git://github.com/softa/hello_drb_world.git
  • 5. Simple (server) require 'drb' class TestServer def doit "Hello, Distributed World" end end server = TestServer.new DRb.start_service('druby://localhost:9000', server) DRb.thread.join
  • 6. Simple (client) require 'drb' DRb.start_service() obj = DRbObject.new(nil, 'druby://localhost:9000') p obj.doit
  • 7. Math (server) require 'drb' class MathServer attr_accessor :total def initialize(initial_value) @total = initial_value end def sum(value) @total += value; end def subtract(value) @total -= value; end def multiply(value) @total *= value; end def divide(value) @total /= value; end end DRb.start_service('druby://localhost:9000', MathServer.new(0)) DRb.thread.join
  • 8. Math (client) require 'drb' DRb.start_service() math = DRbObject.new(nil, 'druby://localhost:9000') puts math.sum(10) puts math.multiply(2) puts math.subtract(5) puts math.divide(3)
  • 9. Math $ ruby client.rb 10 20 15 5 $ ruby client.rb 15 30 25 8
  • 10. Chat (server and client) Open the files... please
  • 11. Agora... BackgrounDRb Fim da digressão.
  • 12. Instalação do BackgrounDRb GEMS necessárias: sudo gem install chronic packet Instalando: script/plugin install git://github.com/gnufied/backgroundrb.git sudo su postgres createuser hello_backgroundrb_world ^d rake db:create rake backgroundrb:setup (...gera migrações...) rake db:migrate DONE!
  • 13. Instalação do BackgrounDRb Todo o código em: http://github.com/softa/hello_backgroundrb_world
  • 14. Iniciando do BackgrounDRb script/backgroundrb start script/backgroundrb start -e ENVIRONMENT
  • 15. Config básico config/backgroundrb.yml --- :backgroundrb: :port: 11006 :ip: 0.0.0.0
  • 16. Conceitos-chave Server Um server que recebe as chamadas. Deve ser startado uma vez junto com o web server. MiddleMan Classe disponível (Factory) no Rails para chamar as tarefas dos workers em background, programar execuções ou busca informação sobre as tarefas. Worker É uma classes que define as tarefas possíveis de se utilizar. Cada worker inicia um processo próprio ao iniciar o server. Job É a execução de um método de um worker.
  • 17. Conceitos-chave cache Hash com informações sobre a execução de um job. job_key Variável disponível no Worker para referenciar unicamente um Job. assync_* Executa o método * em background agora. enq_* Executa o método * em background no futuro.
  • 18. Rake rake -T backgroundrb # Generate a migration for the backgroundrb queue table. rake backgroundrb:queue_migration # Drops and recreate backgroundrb queue table rake backgroundrb:redo_queue # Remove backgroundrb from your rails application rake backgroundrb:remove # Setup backgroundrb in your rails application rake backgroundrb:setup # update backgroundrb config files from your rails application rake backgroundrb:update # Generate documentation for the backgroundrb plugin rake doc:plugins:backgroundrb
  • 19. Gerador script/generate worker WorkerName [options] Rails Info: -v, --version Show the Rails version number and quit. -h, --help Show this help message and quit. General Options: -p, --pretend Run but do not make any changes. -f, --force Overwrite files that already exist. -s, --skip Skip files that already exist. -q, --quiet Suppress normal output. -t, --backtrace Debugging: show backtrace on errors. -c, --svn Modify files with subversion. (Note: svn must be in path) -g, --git Modify files with git. (Note: git must be in path) Description: The worker generator creates stubs for a new BackgrounDRb worker. The generator takes a worker name as its argument. The worker name may be given in CamelCase or under_score and should not be suffixed with 'Worker'. The generator creates a worker class in lib/workers and a test suite in test/unit. Example: ./script/generate worker Tail This will create an Tail worker: Model: lib/workers/tail_worker.rb Test: test/unit/tail_worker_test.rb
  • 20. Executar apenas um método (com Ajax!) script/generate worker Counter CounterController CounterController :: start_counting :: show_count MiddleMan Ajax CounterWorker CounterController :: start :: get_count MiddleMan
  • 21. Worker class CounterWorker < BackgrounDRb::MetaWorker set_worker_name :counter_worker def create(args = nil) end def start cache[job_key] = 0 add_periodic_timer(2) { increment } end def increment cache[job_key] += 1 logger.warn "((#{cache[job_key]}))" end end
  • 22. Controller script/generate controller Count start_counting show_count get_count def start_counting t = Time.now.to_s session[:job_key] = t MiddleMan.worker(:counter_worker) .async_start(:job_key => t) redirect_to :action => :show_count end
  • 23. Controller MiddleMan.worker(:counter_worker) .async_start(:job_key => t)
  • 24. Controller def show_count end # app/views/counter/show_count <h1>Count#show_count</h1> <div id="count"></div> <script> new Ajax.PeriodicalRequest ('count','/counter/get_count') </script>
  • 25. Controller def get_count return render :text => MiddleMan.worker(:counter_worker).ask_result(session[:job_key]) end
  • 26. Resultado
  • 27. Executar um método no futuro friend = Contact.find_by_name 'Rafael Lunardini' MiddleMan.worker(:birthday_worker) .enq_send_congrats(:args => friend, :scheduled_at => friend.birthdate_in_this_year) task = Task.find_by_name 'Reunião Unicórnio' MiddleMan.worker(:task_worker) .enq_notice(:args => task, :scheduled_at => task.next_date)
  • 28. Executar um método periodicamente # config/backgroundrb.yml --- :backgroundrb: :port: 11006 :ip: 0.0.0.0 :schedules: :nightly_worker: :make_nightly_stuff: :trigger_args: 0 30 4 * * * * Igual ao CRON, hum?
  • 29. Executar um método periodicamente Também rola isso: :schedules: :foo_worker: :foobar: :trigger_args: :start: <%= Time.now + 5.seconds %> :end: <%= Time.now + 10.minutes %> :repeat_interval: <%= 1.minute %>
  • 30. Advanced stuff class ConnectorWorker < BackgrounDRb::MetaWorker set_worker_name :connector_worker def chat require 'drb' DRb.start_service() @chat = DRbObject.new(nil, 'druby://localhost:9000') @chat.login("Bot") add_periodic_timer(5) { talk } end def talk @chat.send_message("Bot", "i'm talking...") end end
  • 31. Advanced stuff class TimeServer def receive_data(p_data) end def post_init add_periodic_timer(2) { say_hello_world } end def connection_completed end def say_hello_world p "***************** : invoking hello world #{Time.now}" send_data("Hello Worldn") end end class ServerWorker < BackgrounDRb::MetaWorker set_worker_name :server_worker def create(args = nil) start_server("0.0.0.0",11009,TimeServer) do |client_connection| client_connection.say_hello_world end end end