Thanks, Ryan! I've been using this for a couple of months now to do some pretty hairy background processing and it's been working well. I'm looking forward to seeing your screencast on monitoring these types of processes with God and Monit. Keep it up!
I didn´t quite undestand if I need to modify the vhost.conf if i am using script/server.
Also i didnt find the file on my local machine, I tried with one subdomain and it worked, but when i write request.subdomains.inspect i get an empty array.
Hi,
after installing passenger on my local machine, it works fine :) thanks ryan.
but ... I had some PHP application on localhost that I was accessing like so: localhost/app.
when trying now I get a Routing error: No route matches "/app" with {:method=>:get}.
and don't now what to do, can some body help please.
thanks
i am a rewbie,
i am having trouble getting this to work, i get a
"wrong number of arguments (0 for 1)"
is there anyway to download the example files for this video? thanks for the videos, I look foward to getting this to work :)
As you said in the "Advanced search" screencast it would be nice to clean up the search table from time to time. Is this a good way doing that? I mean shall I have a sleep time for about 24 hours?
This came at a perfect time for me. I'm now successfully using this method but wanted to comment that I had a horrible time debugging my daemon. It seems the log file spits out a lot of confusing errors. Sample:
*** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***
#<MissingSourceFile: no such file to load -- action_mailer/ar_mailer_helper.rb>
*** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<LoadError: no such file to load -- active_support>
The confusing part is that, at least for my env, all of those can be ignored. The more confusing part is that I couldn't figure out how to get a backtrace out of my daemon :( So I spent a good chunk of time on the errors shown in the log only to later realize they were red herrings. I ended up having to do a lot of inspecting of my daemon and finally got it working.
Anyway, it was frustrating. Hopefully the debug situation will get better? All that said, this is a great solution for the problem I had :-D So was worth the trouble.
Hi Ryan, thanks for the screencast.
Just an info. What about the simplest solution? I mean, what do you think to create a method in a given class and then class that method every X minutes by a cron job?
Is there any pros to go with a daemon or stuff like that instead of a cron job? (obviously for methods that can be called every X minutes)
What's the pros and cons of each approach?
(now i'm using a cron job :) )
Using "restart" will do the trick, but if you use the daemon for longer DB tasks, it might be a good idea to stop the daemon before deploying and restarting it afterwards. Because otherwise you might end up migrating a DB you're updating from the daemon at the same moment. This is why I suggested to use :before_update_code and :after_update_code.
Oh, another hint: most people will want to add
RAILS_DEFAULT_LOGGER.auto_flushing = 1
otherwise they will spend hours trying to find out why their production log isn't updated, assuming their daemon code is buggy. The explanation is that production log uses MAX_BUFFER_SIZE = 1000 and no auto flushing, meaning that it will only write to disk once it has 1000 bytes in buffer.
@Jon, if you need a job to be processed on demand then it sounds like Starling + Workling will be a good solution for you.
Another question to ask yourself is how frequently this task will be called. If you expect it to be only once an hour or less then you may want to try Backgroundjob as that will start/stop the Rails process each time. No need to have something constantly running in the background if you're not using it constantly.
@aleco, are you referring to recurring scheduled tasks? This solution was primarily designed for dynamically scheduled tasks where the frequency is not known up front. What you're referring to is definitely possible with one daemon, but the logic can get a little bit tricky in determining what task needs to be run at what given time.
You may want to look into BackgrounDRb for this. It has some cron-like scheduling which will work much better for this kind of thing.
Regarding the deployment, I honestly haven't tried doing this yet. Ideally you should just add a "lib/daemons/mailer_ctl restart" call to your deploy.rb restart task. I'm not certain if this works, if not then I think the fault is with the generator and should be fixed.
1) using this method is tricky if you have more than one schedule, e.g. one every 15sec, one daily and one weekly schedule. Unless you can live with the memory load of having 3 separate daemons (which you usually don't want).
2) add a auto startup/shutdown to the deploy scripts, I guess stopping via :before_update_code might be appropriate.
Hi Ryan. Thanks for great screencasts! I will need one of this solution for background processing, but I'm not sure witch one i should go with. My application will receive xml file via http upload. It's quit time critical data and it has to processed as soon as possible. I can have a daemon that process the files in a directory or go with the solution like workling/starling. /Jon
Scott, Justin -> I get the same problem and fixed it.
If you look in action_controller/mime_type
you'll see that the file has a require at the bottom of it - I assume to 'self -include... er... itself. I'm guessing (haven't done a bug search) at some point someone renamed the file from types to type (dropping the s) and didn't update the 'require' bit. I fixed it in mine by adding
require 'action_controller/mime_type'
before the
Mime::Type.register 'application/pdf', :pdf
require 'pdf/writer'
in my environment.rb file.
@Ryan - thanks for the response. That is correct BJ will load the rails env for each job - however, BJ allows only one copy of itself to run (for a given hostname/rails_env combination) at a time.
So while the loading the rails env will take some cycles, at least processes will not continue to spawn. BJ just handle each job in the queue accordingly. The docs specifically state this was a design decision so as to converse memory.
A pretty reasonable trade-off I'd say. Here are the docs:
http://codeforpeople.rubyforge.org/svn/bj/trunk/README
@Kevin, I'm planning to cover Monit or God to help manage daemon processes in the near future. I may cover daemon controller there too. Thanks for bringing this up.
I want to create a sub domain functionality for my project same as http://hoptoadapp.com/account/new. For that i have read this article(http://railscasts.com/episodes/123-subdomains) and try to do that. I just download the full source code "episode123/blogs" and try to run it on my windows platform. But i get an error message, here it is: ActionController::InvalidAuthenticityToken in BlogsController#create
ActionController::InvalidAuthenticityToken
Is their any solution then please let me inform.
platform:
windows
rails version:2.1.0
add 127.0.0.1 personal.blog.localhost to /etc/hosts file
Ryan,
As part of your series on background processing, have you considered covering daemon_controller (http://github.com/FooBarWidget/daemon_controller/tree/master) by the Phusion guys and how it might tie in with some of these other approaches?
For those getting the MemCacheError, make sure the Starling server is started up and running on the proper port. You may also want to try connecting using IRB as I show at the end of this episode to see if it's a problem with Workling or Starling.
@Jim, I'm investigating BJ as well. It's a bit of a cross between this episode (Workling) and the last one (Rake) because it queues command line calls. This means the Rails app will need to start up each time a job is requested. I'm not too fond of this for frequently recurring jobs, so I may not do an episode on it unless there's some demand.
@purzelrakete, I had trouble getting the github repository working which is why I went with the SVN one here. It looks like it requires fiveruns-memcache-client which may have been my problem. Once you update the README I'll change the instructions here.
@Pimpmaster, I find reporting progress to the user is very application specific. For example, in the case of sending emails, we could update the database every 50 emails and use a bit of math to determine what percentage is done so far. At that point it's just a matter of reporting this to the user, maybe with a polling AJAX request. On second thought, the AJAX part might be a bit interesting and more generic, so I may end up doing one on that.
@Shy, I haven't looked into ar_mailer. I'm mainly using sending email as an example background process and only looking into solutions which will work for other situations. But if you're just sending email it's worth investigating further.
One question - where does the query cache fit in all of this? The example in the Railscast seems to be taken care of by the query cache, for example. Obviously you could modify things in a controller and then cache them, but for this common case, why do anything at all?
Has anyone done any benchmarking of action caching v. render caching (assuming there's fairly little controller work being done)? I might do some if I can't find any, since action caching is meaningfully more difficult to manage.
Looks cool, but (as has been mentioned in the comments already) there are some pretty decent tools out there that facilitate semi-static pages. I've used Comatose successfully and Sandstone looks interesting (it aims to add a embedded CMS functonality using REST practices).
Would love to see a Part 3 on how to provide more feedback to user when jobs re actually completed. Even better, if multiple jobs are being processed, to somehow update the view so user sees whats going on in queue
You didn't try the case where 2 named_scope have a block of code. In your screencast only :recent ha a block of code, but what about chaining it with :cheap that also had a block of code?
I am facing while using workling it gives some error like
FAILED to process queue mailings_workers__send_mailing. #<MailingsWorker:0xb7234db4> could not handle invocation of send_mailing with {:uid=>"mailings_workers:send_mailing:af30186f8c4acff1449353f2a65fbb81", :email=>"kurian_1024@yahoo.co.in"}: wrong number of arguments (1 for 0).
Thanks, Ryan! I've been using this for a couple of months now to do some pretty hairy background processing and it's been working well. I'm looking forward to seeing your screencast on monitoring these types of processes with God and Monit. Keep it up!
Hi,
I didn´t quite undestand if I need to modify the vhost.conf if i am using script/server.
Also i didnt find the file on my local machine, I tried with one subdomain and it worked, but when i write request.subdomains.inspect i get an empty array.
thanks.
Hi,
after installing passenger on my local machine, it works fine :) thanks ryan.
but ... I had some PHP application on localhost that I was accessing like so: localhost/app.
when trying now I get a Routing error: No route matches "/app" with {:method=>:get}.
and don't now what to do, can some body help please.
thanks
a.
I get the following error when trying to send an invite (when I'm logged in):
ActionController::InvalidAuthenticityToken
Any ideas on how to fix this?
i am a rewbie,
i am having trouble getting this to work, i get a
"wrong number of arguments (0 for 1)"
is there anyway to download the example files for this video? thanks for the videos, I look foward to getting this to work :)
As you said in the "Advanced search" screencast it would be nice to clean up the search table from time to time. Is this a good way doing that? I mean shall I have a sleep time for about 24 hours?
:O
Actually, you can just put the line
Mime::Type.register 'application/pdf', :pdf
in mime_types.rb in config\initializers
You'll still need
require 'pdf/writer'
but you can put that in your drawer.rb file and you can leave environment.rb alone.
Really usefull cast...
Ryan,
Excellent tutorial as usual. Passenger was a breeze to setup in Ubuntu with some minor tweaks to the paths that go in Apache's conf.
The guys who wrote Passenger did a fantastic job and installation is cake.
For those who are interested, SliceHost has a nice tutorial for Hardy: http://articles.slicehost.com/2008/5/1/ubuntu-hardy-mod_rails-installation
This came at a perfect time for me. I'm now successfully using this method but wanted to comment that I had a horrible time debugging my daemon. It seems the log file spits out a lot of confusing errors. Sample:
*** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***
#<MissingSourceFile: no such file to load -- action_mailer/ar_mailer_helper.rb>
*** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<LoadError: no such file to load -- active_support>
The confusing part is that, at least for my env, all of those can be ignored. The more confusing part is that I couldn't figure out how to get a backtrace out of my daemon :( So I spent a good chunk of time on the errors shown in the log only to later realize they were red herrings. I ended up having to do a lot of inspecting of my daemon and finally got it working.
Anyway, it was frustrating. Hopefully the debug situation will get better? All that said, this is a great solution for the problem I had :-D So was worth the trouble.
Hi Ryan, thanks for the screencast.
Just an info. What about the simplest solution? I mean, what do you think to create a method in a given class and then class that method every X minutes by a cron job?
Is there any pros to go with a daemon or stuff like that instead of a cron job? (obviously for methods that can be called every X minutes)
What's the pros and cons of each approach?
(now i'm using a cron job :) )
Using "restart" will do the trick, but if you use the daemon for longer DB tasks, it might be a good idea to stop the daemon before deploying and restarting it afterwards. Because otherwise you might end up migrating a DB you're updating from the daemon at the same moment. This is why I suggested to use :before_update_code and :after_update_code.
Oh, another hint: most people will want to add
RAILS_DEFAULT_LOGGER.auto_flushing = 1
otherwise they will spend hours trying to find out why their production log isn't updated, assuming their daemon code is buggy. The explanation is that production log uses MAX_BUFFER_SIZE = 1000 and no auto flushing, meaning that it will only write to disk once it has 1000 bytes in buffer.
@Jon, if you need a job to be processed on demand then it sounds like Starling + Workling will be a good solution for you.
Another question to ask yourself is how frequently this task will be called. If you expect it to be only once an hour or less then you may want to try Backgroundjob as that will start/stop the Rails process each time. No need to have something constantly running in the background if you're not using it constantly.
@aleco, are you referring to recurring scheduled tasks? This solution was primarily designed for dynamically scheduled tasks where the frequency is not known up front. What you're referring to is definitely possible with one daemon, but the logic can get a little bit tricky in determining what task needs to be run at what given time.
You may want to look into BackgrounDRb for this. It has some cron-like scheduling which will work much better for this kind of thing.
Regarding the deployment, I honestly haven't tried doing this yet. Ideally you should just add a "lib/daemons/mailer_ctl restart" call to your deploy.rb restart task. I'm not certain if this works, if not then I think the fault is with the generator and should be fixed.
Ryan, in case you're planning to add a followup:
1) using this method is tricky if you have more than one schedule, e.g. one every 15sec, one daily and one weekly schedule. Unless you can live with the memory load of having 3 separate daemons (which you usually don't want).
2) add a auto startup/shutdown to the deploy scripts, I guess stopping via :before_update_code might be appropriate.
For integration testing you can define session[:user] by adding a second hash, for the session.
get "users/1/edit", {}, {:user_id => 1}
... but this doesn't seem to work for profiling, for some reason.
Hi Ryan. Thanks for great screencasts! I will need one of this solution for background processing, but I'm not sure witch one i should go with. My application will receive xml file via http upload. It's quit time critical data and it has to processed as soon as possible. I can have a daemon that process the files in a directory or go with the solution like workling/starling. /Jon
@fred, the Rails environment will be loaded when the daemon starts. At that point it will stay loaded for each job.
Fred C - DG does load the rails env when the job is picked up. By default this is production, but you could change it to whatever you wished.
Cool, Ryan!
Definitely looking forward to seeing some AJAX love on this one.
Cheers :)
Great episode.
Just a quick question - does this method load the rails env when the job is picked up?
Thanks.
Hi, great tutorial - keep them coming!
Scott, Justin -> I get the same problem and fixed it.
If you look in action_controller/mime_type
you'll see that the file has a require at the bottom of it - I assume to 'self -include... er... itself. I'm guessing (haven't done a bug search) at some point someone renamed the file from types to type (dropping the s) and didn't update the 'require' bit. I fixed it in mine by adding
require 'action_controller/mime_type'
before the
Mime::Type.register 'application/pdf', :pdf
require 'pdf/writer'
in my environment.rb file.
Hope that helps.
After following this tutorial I'm having trouble. I cannot get the "remember me" function to work. Has anyone else experienced this?
Great videos, Ryan! Keep up the great work!
Ryan, nicely done. I'm very pleased to hear you are planning a future episode on monit and god. Thanks
thanks Ryan, I was using the OpenWFEru scheduler, but I preffer this method, this is exactly what I was looking for.
@Ryan - thanks for the response. That is correct BJ will load the rails env for each job - however, BJ allows only one copy of itself to run (for a given hostname/rails_env combination) at a time.
So while the loading the rails env will take some cycles, at least processes will not continue to spawn. BJ just handle each job in the queue accordingly. The docs specifically state this was a design decision so as to converse memory.
A pretty reasonable trade-off I'd say. Here are the docs:
http://codeforpeople.rubyforge.org/svn/bj/trunk/README
@Yann, fixed now. Thanks for pointing this out.
@Kevin, I'm planning to cover Monit or God to help manage daemon processes in the near future. I may cover daemon controller there too. Thanks for bringing this up.
I want to create a sub domain functionality for my project same as http://hoptoadapp.com/account/new. For that i have read this article(http://railscasts.com/episodes/123-subdomains) and try to do that. I just download the full source code "episode123/blogs" and try to run it on my windows platform. But i get an error message, here it is: ActionController::InvalidAuthenticityToken in BlogsController#create
ActionController::InvalidAuthenticityToken
Is their any solution then please let me inform.
platform:
windows
rails version:2.1.0
add 127.0.0.1 personal.blog.localhost to /etc/hosts file
Thanks,
Soumya
Ryan,
As part of your series on background processing, have you considered covering daemon_controller (http://github.com/FooBarWidget/daemon_controller/tree/master) by the Phusion guys and how it might tie in with some of these other approaches?
Thanks and keep the great screencasts coming! :)
For those getting the MemCacheError, make sure the Starling server is started up and running on the proper port. You may also want to try connecting using IRB as I show at the end of this episode to see if it's a problem with Workling or Starling.
@Jim, I'm investigating BJ as well. It's a bit of a cross between this episode (Workling) and the last one (Rake) because it queues command line calls. This means the Rails app will need to start up each time a job is requested. I'm not too fond of this for frequently recurring jobs, so I may not do an episode on it unless there's some demand.
@purzelrakete, I had trouble getting the github repository working which is why I went with the SVN one here. It looks like it requires fiveruns-memcache-client which may have been my problem. Once you update the README I'll change the instructions here.
@Pimpmaster, I find reporting progress to the user is very application specific. For example, in the case of sending emails, we could update the database every 50 emails and use a bit of math to determine what percentage is done so far. At that point it's just a matter of reporting this to the user, maybe with a polling AJAX request. On second thought, the AJAX part might be a bit interesting and more generic, so I may end up doing one on that.
@Shy, I haven't looked into ar_mailer. I'm mainly using sending email as an example background process and only looking into solutions which will work for other situations. But if you're just sending email it's worth investigating further.
How would I add this to my demo and test environments?
I want basic authentication based on environemt
Sorry! I misunderstood your question! I had the same problem actually. What does your HTML look like for your "states" in your form?
One question - where does the query cache fit in all of this? The example in the Railscast seems to be taken care of by the query cache, for example. Obviously you could modify things in a controller and then cache them, but for this common case, why do anything at all?
Here's a quick example of how you can use Populator and Faker to create valid records for use in demos, acceptance testing, etc:
http://almosteffortless.com/2008/09/27/creating-valid-records-with-populator-and-faker/
@Cassiano, Thanks for pointing these problems out! Fixed.
Has anyone done any benchmarking of action caching v. render caching (assuming there's fairly little controller work being done)? I might do some if I can't find any, since action caching is meaningfully more difficult to manage.
Hi Ryan,
Do you have any opinion about ar_mailer for this purpose?
http://blog.segment7.net/articles/2006/08/15/ar_mailer
Thanks!
@QQ
Yeah, sorry, my code example didn’t work. I ended up using the session object to get it working: http://pastie.org/280240
Looks cool, but (as has been mentioned in the comments already) there are some pretty decent tools out there that facilitate semi-static pages. I've used Comatose successfully and Sandstone looks interesting (it aims to add a embedded CMS functonality using REST practices).
Hey, great show. I'm very very new to RoR and still got it working!
However I'd like to make it so if no results are shown it shows a message, not display all. How is this possible in rails?
Thanks :)
Awesome railcast!!
Do you have any idea's on generating spreadsheet documents?
Thanks so much!
rugger
I have created a plugin that implements this functionality. Please check it out here: http://github.com/sixty4bit/acts_as_virtual_attribute
I used the older should_destroy? method instead of creating a blank array in the container.
Why did I create this plugin? Because my current project has 50 of these on one model.
Excellent 'cast, Ryan :)
Would love to see a Part 3 on how to provide more feedback to user when jobs re actually completed. Even better, if multiple jobs are being processed, to somehow update the view so user sees whats going on in queue
@8 Regarding the start command:
You can make sure your cmd windows close after the emails are sent like this:
start cmd /c "title Email@%TIME% & cd c:/www & rake -T > emails.log 2>&1"
/c closes cmd window
2>&1 redirects STDERR
Hi,
You didn't try the case where 2 named_scope have a block of code. In your screencast only :recent ha a block of code, but what about chaining it with :cheap that also had a block of code?
I can't make it work.
@kurian your worker methods need to have an 'options' argument.
I am facing while using workling it gives some error like
FAILED to process queue mailings_workers__send_mailing. #<MailingsWorker:0xb7234db4> could not handle invocation of send_mailing with {:uid=>"mailings_workers:send_mailing:af30186f8c4acff1449353f2a65fbb81", :email=>"kurian_1024@yahoo.co.in"}: wrong number of arguments (1 for 0).
restful_authentication X 2 I would like to know the best approach for this as well
okay, the documentation needs a good update - agreed ;).
i'll fix it up within the next day and write a post up on http://playtype.net. i'll open a group on google groups, too.
and i'll keep the svn repo synched, after all, so that the instructions here keep working.
if anybody needs help setting this up, drop me a line and i'll do what i can!
glad that people are finding workling useful :)
i've tried to keep the svn repo synched with github, this hasnt really worked out so well ;). i think i'lll just kick it to the curb.
@andy: the README might be a bit out of date - i'll update this asap.
@wilson re: the memcache error: i'll look into this now. a few people have had this, probably just a case of old README instructions.