
Security News
ECMAScript 2025 Finalized with Iterator Helpers, Set Methods, RegExp.escape, and More
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
SayWhen is a job scheduling library for use in any project, but with a few extra hooks for rails projects. It was roughly inspired by the Quartz scheduler.
You add it to a ruby program (optionally configure it) and then schedule jobs using a few different strategies, with cron-like expressions the most powerful.
When scheduling, you specify a trigger which controls when execution will occur, such as a cron trigger, or an execute only once trigger, and a job, which is the actual work to perform.
The cron triggers are based on the extended cron capabilities.
Jobs can be stored different ways, either in memory (e.g. loaded on start from a ruby file), or saved to a database.
The scheduler can execute the jobs in different ways, either by loading and running them itself synchronously, or by delegating the processing to ActiveJob.
SayWhen can be run either in its own process, or can run as a supervised actor in a Celluloid process (e.g. sidekiq or shoryuken).
Add this line to your application's Gemfile:
gem 'say_when'
And then execute:
$ bundle
Or install it yourself as:
$ gem install say_when
To use, first configure how jobs are stored and processed. Be default, they are in memory, and processed synchronously, but that can be configured to behave differently.
The currently available storage options are:
The processor options are:
You also have some options for running SayWhen:
Finally, there are options for triggers that determine when jobs run:
# config/intializers/say_when.rb
require 'say_when'
# you can specify a the logger
SayWhen.logger = Rails.logger
# configure the scheduler for how to store and process scheduled jobs
# it will default to a :memory strategy and :simple processor
SayWhen.configure do |options|
options[:storage_strategy] = :active_record
options[:processor_strategy] = :simple
end
There is a very verbose way to create a scheduled job, setting the options for the trigger and job explicitly, and then some helper methods that make this easier for common cases.
Here is an example of the verbose way of scheduling a job, which is a good place to start:
job = SayWhen::Scheduler.schedule(
trigger_strategy: 'once',
trigger_options: { at: 10.second.since },
job_class: SomeTask,
job_method: 'execute',
data: { id: 123 }
)
There are also convenience methods on the Scheduler
:
Besides storing jobs in ActiveRecord, you can also associate jobs with other models.
There is an acts_as_scheduled
method you can call in an ActiveRecord class for this purpose.
It both makes it easier to schedule a job, and to see manage the list of related jobs.
For example, you might create a job to send a reminder a week after a user is created, and relate this new job to that user.
By associating it with the ActiveRecord
object, you can more easily manage this reminder, such as canceling it if they close their account.
When using ActiveRecord
integration in Rails, there is a generator for the migration to create the tables for saving scheduled jobs:
bundle exec rails generate say_when:migration
The resulting migration assumes the scheduled jobs will use a integer based id column, please update the default migration if this is not the case in your system:
# change this to string or other type as needed
t.integer :scheduled_id
The SimplePoller
does what you would expect; when you run it, it starts up a loop of checking for jobs to run, sleeping, and then checking again.
It can be executed from the rake task:
bundle exec rake say_when:start
But that isn't doing much except loading the environment then this:
require 'say_when'
require 'say_when/poller/simple_poller'
SayWhen::Poller::SimplePoller.start
For my own purposes, I use things like daemontools
and god
to daemonize, so this has been enough for me, but it would not be hard to write a command line script for it.
Most of the time I am also running a job processor, either shoryuken
or sidekiq
, and I would prefer to piggyback on that same process instead of starting up another. Since both of those use Celluloid (or did, Sidekiq no longer does), I also created a Celluloid actor class that can be added to the celluloid based job process via hooks in their startup.
For Shoryuken, add this to your initializer (probably config/initializers/shoryuken.rb
):
require 'say_when/poller/celluloid_poller'
Shoryuken.on_start do
# check for new jobs to run every 5 seconds
SayWhen::Poller::CelluloidPoller.supervise_as :say_when, 5
end
For Sidekiq, there is a slightly different syntax, but basically the same idea (via https://github.com/mperham/sidekiq/wiki/Deployment#events):
require 'say_when/poller/celluloid_poller'
Sidekiq.configure_server do |config|
config.on(:startup) do
SayWhen::Poller::CelluloidPoller.supervise_as :say_when, 5
end
end
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)FAQs
Unknown package
We found that say_when demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.
Research
North Korean threat actors linked to the Contagious Interview campaign return with 35 new malicious npm packages using a stealthy multi-stage malware loader.