My environment is Macbook OSX 10.7 Lion with Ruby 2.0 and Rails 4.
I am new to RoR. I built a website with one column database using a scaffold.
It's just a little website about weather.
I want to input degrees to database every hour.
And I found the gem clockwork, but I have no idea how to use it with my project.
I wrote clock.rb and put it in my project file and ran rails s but nothing happened.
Here is myproject/clock.rb
myproject/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
puts "Running #{job}"
every(1 hours, ''){
Mydata.create(:degree => input_data)
}
end
What should I do with it or where should I put the file?
They say that I need to use $ clockwork clock.rb, but when I run rails s, there's no way to use that...
Thanks a lot.
As stated in the official docs you need a couple of things.
setup the clock file, I've set it in app/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
case job
when 'weather.input_degree'
Mydata.create degree: input_data
# when 'some_other_task'
# ...
else
puts "Couldn't find your job!"
end
end
every(1.hour, 'weather.input_degree') # the string indicates an arbitrary job name
# every(20.seconds, 'weather.some_other_task')
end
The starting process. The key is to use something like Foreman
$ gem install foreman
Create a file named Procfile in root of your app:
web: bundle exec rails -s
clock: bundle exec clockwork app/clock.rb
# any_other_service_you_want: bash script here
start your server
$ foreman start
Add to Gemfile
gem 'clockwork'
after adding upper listed gem in gemfile, use bundle install to add this gem into project.
Example
Create a file clock.rb under /lib directory
clock.rb
require File.expand_path('../../config/boot', __FILE__)
require File.expand_path('../../config/environment', __FILE__)
require 'clockwork'
include Clockwork
module Clockwork
## Here Student is a domain class, having a method insertRecord to
## insert a record in DB
every(20.seconds, 'job Inserting Record in DB') { Student.insertRecord }
end
Command to Run the clockword
bundle exec clockwork lib/clock.rb
This code needs stay outside of handler block:
every(1.hour, ''){ Mydata.create(:degree => input_data) }
You can execute the clock like that:
bundle exec clockwork clock.rb
You can make use of Cron. Write a rake task and call the rake task from the Cron for repeating processes.
Example (Add this to cron to run the task every hour):
0 * * * * cd /home/projectdir;rake do:task
Related
I am using clockwork gem. I want to automatically delete all comments from comments table every day at midnight.
This app/clock.rb script is working as it supposed to in development env.:
require './config/boot'
require './config/environment'
require 'clockwork'
module Clockwork
every(1.day, 'delete.comment', at: '00:00') {
Comment.destroy_all
}
end
when it's running on my local terminal with $ clockwork app/clock.rb.
So I deployed the app to Heroku. Later in a terminal, I run:
RAILS_ENV=production rails r app/clock.rb
as in this SO topic but only output is:
Running via Spring preloader in process 13973
and it quits to prompt and comments are still there (assuming the value in at: hash has passed).
This is my first individual project.
My question is how to make this script running nonstop in production to remove comments automatically every day at midnight?
OR
more general:
how to run script nonstop in production.
I read this SO topic but the answers are not very thorough and first link above is neither, as for a beginner to understand.
You can create rake task and call form clock.rb
every(1.day, 'name', at: '09:00') do
#Load task
Rake::Task['comment:destroy'].invoke
end
rake task:
lib/tasks/comment.rake
namespace :comment do
desc 'Destroy all comment'
task destroy: :environment do
Comment.destroy_all
end
end
Thanks for effort. After all, I managed this by rake task and without clockwork gem.
I created a rake task, deploy it to heroku, and ran task through heroku scheduler addon. Now it's running as a background job.
I deploy my project using passenger & nginx & Amazon EC2.
How can i run clock task on server. I used Clockwork gem.
This is my clock task (lib/clock.rb) :
# require boot & environment for a Rails app
require_relative "../config/boot"
require_relative "../config/environment"
require 'clockwork'
module Clockwork
handler do |job|
puts "Running #{job}"
end
every 10.minutes, 'send detail' do
::User.periodically_send_detail
end
end
Locally i can run bundle exec clockwork lib/clock.rb and it's working. It send detail on every 10 seconds.
On heroku i add bundle exec clockwork lib/clock.rb to Procfile like (NOTE: extra charge will be applied for clock) :
clock: bundle exec clockwork lib/clock.rb
Works on heroku also.
But how can i run this clock file with passenger and nginx and Amazon EC2 server on production startup ?
Any extra information required then tell me i will provide.
I access server via SSH.
I change gem to whenever gem and it doing job well.
Add to gem file :
gem 'whenever', :require => false
Then run wheneverize .
Then add task to config/schedule.rb fiile :
every 10.minutes do
runner "User.periodically_send_student_detail", :output => 'cron.log'
end
Then update your crontab in ubuntu server using this command :
$ whenever --update-crontab --set environment='production'
and that's it. It's done.
You can check cronjob using this command crontab -e OR crontab -l
I have a repo for multiple deployment with using capistrano-multiconfig gem. The problem is that for some applications I want to require sikideq tasks. Something like this:
if fetch(:sidekiq_enabled?)
require 'capistrano/sidekiq'
require 'capistrano/sidekiq/monit'
end
I guess that Capfile is loaded before the capistrano configs. How to deal with this?
I was in the same situation, I wanted to require some gems per project and since my command line pattern is always the same to execute capistrano tasks, this is how I deal with it.
My pattern is like this:
$ bundle exec cap project:stage namespace:task
The solution was for me to get the first argument (here project) to know what kind of project it is and require the good recipe for the project.
So in Capfile, I write something like this
[...]
# Get project from the command line if any
current_project = ARGV[0].split(':')[0]
magento_projects = ["project_1"]
symfony_projects = ["project_2"]
# Include required tasks per project
if magento_projects.include?(current_project)
require 'capistrano/magento'
end
if symfony_projects.include?(current_project)
require 'capistrano/symfony'
end
[...]
Now when I type :
$ bundle exec cap project_1:staging deploy
Or :
$ bundle exec cap project_2:production deploy:check
It'll require different gems. Done :)
Having a series of rake tasks that should be translated by the whenever gem into the cron file, I was wondering why the takes shows were pointing to an old release.
It cannot be asserted that whenever is active somehow, even though it is listed in the gem file (and associated lock file) and deployment refers to whenever in the deployment as follows:
tar: DEBUG [1f7d4e56] bin/whenever: time stamp 2016-01-08 15:01:20 is 88.787104175 s in the future
update Checking bundle exec whenever -v returns the proper version. Need bundle exec there...
Capfile includes require "whenever/capistrano" after calls to bundler and rails.
require 'capistrano/bundler'
require 'capistrano/rails'
require 'whenever/capistrano'
Note: this is being tested in development mode.
Functional answer. The instructions are misleading If you don't need different jobs running on different servers in your capistrano deployment, then you can safely stop reading now and everything should just work the same way it always has. Keep on reading.
The nugget is nested after this statement. Roles default to [:db]. Thus two sources of error are possible:
different job_roles on different machines are not specified in schedule.rb
Check your environment file. If "db" is not listed, whenever will not fire.
I had the same issues with using Capistrano whenever plugin, I solved it by making custom deploy shell scripts, cap production deploy being one command of many, and then inclding cap production cron:regen; inside this script I called deploy.sh, with the command inside the deploy.rb being:
namespace :cron do
desc "restart cron"
task :regen do
on roles(:app) do |host|
rails_env = fetch(:stage)
execute_interactively "crontab -r;bundle exec whenever --update-crontab;crontab -l;"
end
end
end
def execute_interactively(command)
port = fetch(:port) || 22
exec "ssh root##{fetch(:ip)} -t 'cd SERVER_PATH_OF_YOUR_APP && #{command}'"
end
I use these functions for all types of different commands, since Capistrano still gives me problems with a lot of native plugins it uses.
If you're not happy with the whenever/capistrano, you can create yourself a simple Capistrano task to update the cron jobs:
namespace :deploy do
desc "Update crontab with whenever"
task :update_cron do
on roles(:app) do
within current_path do
execute :bundle, :exec, "whenever --update-crontab #{fetch(:application)}"
end
end
end
after :finishing, 'deploy:update_cron'
end
The task will be called when the code deployment is finished.
I'm folowing this link to put ruby on rails start automatically.
But I cant understand its ruby code
#!/usr/bin/env ruby
require File.expand_path("../../config/environment", __FILE__) #1.what is this path?
STDOUT.sync = true
Stalker::job 'user.fetch_details' do |args| #2.what is this user?
begin
user = User.find(args['id']) #3.what is this id?
user.fetch_user_details!
rescue ActiveRecord::RecordNotFound # too fast
Rails.logger.warn "Unable to find user ##{args['id']} - suspect too fast, requeuing"
Stalker.enqueue('user.fetch_details', :id => args['id'])
end
end
jobs = ARGV.shift.split(',') rescue nil
Stalker.work jobs
and conf file code in /etc/init/
description "TweetedLinks Ruby Worker"
# automatically start
start on filesystem
# working directory
chdir /var/www/TweetedLinks/current #4.should I change this to my own dir?ie home/usr/Trail/test-app
# command to run, with Bundler support!
env RAILS_ENV=production
exec bundle exec ruby script/worker.rb >> log/worker.log #5.do i need to create this worker.log? and this script folder can be put anywhere?
respawn
I have my rails app under home/usr/Trail/test-app
I have create a script folder under home/usr/script
I have my rvm generated under home/usr/.rvm/wrapper/test-app
How to modify this code according to my situation.
and the 5 question in code comments I also very confuse.
Thanks in advance!have been stuck for month!
The easiest way would be to use foreman gem that can export Procfile to upstart, see http://ddollar.github.io/foreman/#UPSTART-EXPORT