8

The physical architecture of the production environment includes several machines doing different jobs (rake tasks), all of them over the same database.

One of the jobs would do a large UPDATE over a table that usually returns a postgres deadlock if the other jobs are running.

I already have a rake task to gracefully stop the other jobs, but I can only execute it from the local machines.

What I want to achieve is:

task :big_update => :environment do
  stop_tasks_on_another_servers

  # do the SQL UPDATE
  ...
end

where the stop_tasks_on_another_servers should execute a rake task on the other servers.

My best try was to use the https://github.com/capistrano/sshkit gem. The same that Capistrano uses it, but I'm still missing a step here. I'm trying the following on a rails console in the production machine:

require 'sshkit/dsl'
hosts = ['machine1', 'machine2']

on hosts do
  within "/home/me/project/current" do
    with rails_env: :production do
      rake "stop_tasks"
    end
  end
end

But it returns:

INFO [70a0610a] Running /usr/bin/env rake stop_tasks on machine1
SSHKit::Command::Failed: rake stdout: Nothing written

What am I missing or is there an easier way to execute remote tasks?

dcarneiro
  • 7,060
  • 11
  • 51
  • 74
  • Why do you have multiple production nodes running different jobs at the first place? You can add 1 node which can be responsible for just running your rake tasks, In that case you won't have to manage multiple nodes – Jasdeep Singh Dec 16 '13 at 16:13
  • @JasdeepSingh Some of the rake tasks (the ones that are feeding the system) are running 24/7 and using all the 8 cores on two different machines. I loose a lot of performance if all the tasks were running on the same node. – dcarneiro Dec 16 '13 at 16:22
  • 1
    Have you seen this? https://github.com/seattlerb/rake-remote_task. I don't have experience with it but it looks very useful. – Josh Dec 16 '13 at 17:20
  • @Josh, that gem was really useful. It allows to call rake tasks remotely and with a little teaks I was able to call it from inside my own task. If you place your comment on an answer I'll gladly mark it as accepted. – dcarneiro Dec 17 '13 at 10:31

2 Answers2

3

Check out Rake Remote Task. Here is a snippet to show you how it works:

require 'rake/remote_task'

set :domain, 'abc.example.com'

remote_task :foo do
  run "ls"
end
Josh
  • 5,631
  • 1
  • 28
  • 54
0

I've had success using this approach:

http://gistflow.com/posts/372-execute-rake-task-on-remote-server-with-capistrano

bryanp
  • 427
  • 3
  • 9