How to run jruby script from MRI ruby rails app? - ruby-on-rails

I have a script written with jRuby and I need this script to be executed from rails app (which runs on MRI ruby). I have code like this:
class User < ActiveRecord::Base
def run_script!
system "jruby /path/to/my/script/script.rb #{id}"
end
end
and it works in development! But on Ubuntu production server it returns nil and I have no idea how to make it work.

From the Kernel#system documentation:
Returns nil if command execution fails. An error status is available in $?.
So what does $? tell you?

Related

Whenever gem - runner failing for one Model? Illegal name?

I have a model called Task.
rails runner -e development "Task.myClassMethod"
Results in this:
Please specify a valid ruby command or the path of a script to run.
Run 'bin/rails runner -h' for help.
undefined method `myClassMethod' for Thor::Command:Class
This works in any of my other models. I tried clearing out my Task model:
class Task < ApplicationRecord
def self.myClassMethod
pp 'Hello'
end
end
I've also tried running rails app:update:bin per this thread: https://github.com/javan/whenever/issues/663
But still getting the same errors. Is this a naming conflict?

Rails 4: Delayed job keep cache for email "from" header value

I am developing a mailing web application in Ruby on Rails and I am in front of an issue with delayed_job gem:
In the settings of my application, I give the ability for the customer to update the email address from where mailing are sent. But I discovered there was something like a cache from delayed_job which doesn’t use the update email address for the « from » header.
When I use the delayed_job task by Capistrano manually it works so I tried to add a callback after_update in my model to handle the restart of delayed_job but without any success.
Capistrano command:
cap <my_env> delayed_job:restart # this works but it’s a manual command so useless in my case
What I tried is to dynamically restart delayed_job from the model:
class Setting < ActiveRecord::Base
after_save :restart_delayed_job
def restart_delayed_job
if email_changed?
system "RAILS_ENV=#{Rails.env} do bundle exec bin/delayed_job -n 1 restart"
end
end
end
My Mailing class:
class MyMailer < ApplicationMailer
default from: Setting.first.email # After updating the email value in setting, it still the old one used.
# more code skipped
end
Does anyone knows how can I restart delayed_job from Rails ?
Is there a way to do it exclusively in Ruby without writing shell script ?
In order to help me to understand better, is there several instance of delayed_job (one by website in the server) or one for all website ?
Thanks for your help !
My project:
- Rails 4.2.5
- Ruby 2.2.2
- ActiveAdmin 1.0.0 pre2
- Delayed job 4.1.1
- Capistrano 3.4.0
The solution was to move the from header into the mail function.
The reason is the default from is set only once when the application start and cannot be changed this way.
mail(from: email, subject: subject, ...) do
# skipped code
end
Here is the answer who helped me to understand that: https://github.com/collectiveidea/delayed_job/issues/882

How to run some default commands after firing the Rails console?

I need to run a few commands whenever I start my Rails console, like setting up the logger, or to set the time to my time zone.
Right now I'm copying and pasting these commands after Rails is started. Can I write a script to make these commands run automatically after IRB is started?
Rails' console is IRB. IRB supports an .irbrc file, which contains initialization information and settings.
Read "https://stackoverflow.com/questions/123494/whats-your-favourite-irb-trick" and "My .irbrc for console/irb" for ideas.
I wrote an extended answer to this in another question but the short answer is that if you are using Rails 3 or above you can use the console method on YourApp::Application to make it happen:
module YourApp
class Application < Rails::Application
...
console do
Time.zone = A.info.time_zone
end
end
end

start thinking sphinx on rails server startup

I have a chain of nginx + passenger for my rails app.
Now after each server restart i need to write in terminal in project folder
rake ts:start
but how can i automatize it?
So that after each server restart thinking sphinx is automatically started without my command in terminal?
I use rails 3.2.8 and ubuntu 12.04.
I can not imagine what can i try ever, please help me.
How can i do this, give some advices?
What I did to solve the same problem:
In config/application.rb, add:
module Rails
def self.rake?
!!#rake
end
def self.rake=(value)
#rake = !!value
end
end
In Rakefile, add this line:
Rails.rake = true
Finally, in config/initializers/start_thinking_sphinx.rb put:
unless Rails.rake?
begin
# Prope ts connection
ThinkingSphinx.search "test", :populate => true
rescue Mysql2::Error => err
puts ">>> ThinkingSphinx is unavailable. Trying to start .."
MyApp::Application.load_tasks
Rake::Task['ts:start'].invoke
end
end
(Replace MyApp above with your app's name)
Seems to work so far, but if I encounter any issues I'll post back here.
Obviously, the above doesn't take care of monitoring that the server stays up. You might want to do that separately. Or an alternative could be to manage the service with Upstart.
If you are using the excellent whenever gem to manage your crontab, you can just put
every :reboot do
rake "ts:start"
end
in your schedule.rb and it seems to work great. I just tested on an EC2 instance running Ubuntu 14.04.
There's two options I can think of.
You could look at how Ubuntu manages start-up scripts and add one for this (perhaps in /etc/init?).
You could set up monit or another monitoring tool and have it keep Sphinx running. Monit should boot automatically when your server restarts, and so it should ensure Sphinx (and anything else it's tracking) is running.
The catch with Monit and other such tools is that when you deliberately stop Sphinx (say, to update configuration structure and corresponding index changes), it might start it up again before it's appropriate. So I think you should start with the first of these two options - I just don't know a great deal about the finer points of that approach.
I followed #pat's suggestion and wrote a script to start ThinkingSphinx whenever the server boots up. You can see it as a gist -
https://gist.github.com/declan/4b7cc4fb4926df16f54c
We're using Capistrano for deployment to Ubuntu 14.04, and you may need to modify the path and user name to match your server setup. Otherwise, all you need to do is
Put this script into /etc/init.d/thinking_sphinx
Confirm that the script works: calling /etc/init.d/thinking_sphinx start on the command line should start ThinkingSphinx for your app, and /etc/init.d/thinking_sphinx stop should stop it
Tell Ubuntu to run this script automatically on startup: update-rc.d thinking_sphinx defaults
There's a good post on debian-administration.org called making scripts run at boot time that has more details.

Delayed_job and Prawn scripts

How do I run Prawn scripts with Delayed_job.
(Currently using Bj but not supported in Rails3)
This code does not work.
/lib/report_job.rb
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
bundle exec rails runner "#{Rails.root}/jobs/#{prawn_script_name}.rb #{#current_user.account_id} "
end
/reports_controller.rb
def generate_report(prawn_script_name)
Delayed::Job.enqueue(ReportJob.new("#{prawn_script_name}.rb","#{#current_user.account_id}"))
end
delayed_job table is populated as expected.
--- !ruby/struct:ReportJob
prawn_script_name: statements.rb
account_id: '18'
Error in last_error field.
{undefined method `runner' for ReportJob:0xc28f080
Any suggestions?
I think there are several misunderstandings here:
you meant to call runner from outside your app, e.g., in a shell script or command line. in other words, bundle exec rails runner are all commands and arguments of commands, not ruby methods or variables. runner is the first expression that is eval'd inside your perform method, hence your error.
rails runner just brings up your apps environment and evals the string or path argument given.
note account_id within the perform task, another mistake in your code I guess.
What you wanted to do could be a simple system call.
It seems your prawn script needs the environment, so simply calling
system "ruby #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
won't work.
Now you could surely execute the script with runner from your project directory.
system "bundle exec rails runner #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
but doing this via a system call within your environment is quite redundant. Delayed jobs already have access to your rails environment. so just simply load them.
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
load "#{Rails.root}/jobs/#{prawn_script_name}.rb"
end
end
hope this helps

Resources