Scheduling stuff in the future
You need to create an ActionJob
with rails generate job your_job_name
.
Then you can delay its execution
YourJob.set(wait_until: 1.day.from_now)
For this to work you indeed need a Job queue to be configured for your project. I personally recommend Sidekiq
Sadly, you will have a hard time avoiding setting up a gem for this.
How to schedule a function to execute at a future time?
With DelayedJob you can do something like
def in_the_future
# Some other code
end
handle_asynchronously :in_the_future, :run_at => Proc.new { 10.hours.from_now }
Very nice? :) I suggest you read the documentation as linked by jared
Schedule a task in days or months
take a look at whenever gem
Seems like using
every '0 0 23 12 *' do
...
end
would work for this. It can take cron syntax so minute hour day month day-of-week
. So this will run every December 23rd at 12:00am regardless of what day of the week that is.
Is it a bad idea to use a future inside a singleton class?
This isn't necessarily a bad thing. The Future will make sure that the objects returned will be visible across threads. The thread pool is fixed at size of 1, so if there are concurrent requests the second one blocks until the only worker thread becomes available, by which time it has handed off its results from the previous task. No overlap should be occurring.
rails periodic task
Generally speaking, there's no built in way that I know of to create a periodic task within the application. Rails is built on Rack and it expects to receive http requests, do something, and then return. So you just have to manage the periodic task externally yourself.
I think given the frequency that you need to run the task, a decent solution could be just to write yourself a simple rake task that loops forever, and to kick it off at the same time that you start your application, using something like Foreman. Foreman is often used like this to manage starting up/shutting down background workers along with their apps. On production, you may want to use something else to manage the processes, like Monit.
How do I wait for multiple asynchronous operations to finish before sending a response in Ruby on Rails?
I ended up answering my own question after some more research into the concurrent-ruby library. Future
s ended up being what I was after! Simply put, they execute a block of code in a background thread and attempting to access the Future's calculated value blocks the main thread until that background thread has completed its work. My Rails controller actions end up looking like:
def index
op1 = Concurrent::Future.execute { get_request }
op2 = Concurrent::Future.execute { another_request }
render text: "The result is #{result(op1.value, op2.value)}."
end
The line with render
blocks until both async tasks have finished, at which point result
can begin running.
Related Topics
How to Negate a Scope in Rails
How to Make a Check Box Default to Being "Checked" in Rails 1.2.3
Is There a Ruby One-Line "Return If X"
Programmatically Getting Full Ruby Version
Does Ruby Support Unicode and How Does It Work
Import SASS Partial Over Http Instead of Filesystem
How to Use the Ruby "Self" Keyword
Run a Cli Thor App Without Arguments or Task Name
Heroku Rejecting Push in Mature Application (Pre-Receive Hook Declined)
Create Hash from Array and Frequency
"Gem Update --System Is Disabled on Debian" Error
Datetime with Mongodb/Mongoid and Rails 3 Not Populating
Are There Any Ruby Orms Which Use Cursors or Smart Fetch