Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
que-rails
contains assorted tools that integrate the Que job queue into a Rails application. It provides rake tasks and a railtie that handles spinning up the background worker pool.
This document covers basic information on setting up and using Que in a standard Rails application, and assumes you're using Rails 4. que-rails
isn't tested with versions of Rails before 4, and may or may not work with them. For information on more advanced usage of Que, see its documentation.
Add this line to your application's Gemfile:
gem 'que-rails'
And then execute:
$ bundle
Or install it yourself as:
$ gem install que-rails
First, generate and run a migration for the que_jobs
table.
$ bin/rails generate que:install
$ bin/rake db:migrate
Create a class for each type of job you want to run:
# app/jobs/charge_credit_card.rb
class ChargeCreditCard < Que::Job
# Default settings for this job. These are optional - without them, jobs
# will default to priority 100 and run immediately.
@priority = 10
@run_at = proc { 1.minute.from_now }
def run(user_id, options)
# Do stuff.
user = User.find(user_id)
card = CreditCard.find(options[:credit_card_id])
ActiveRecord::Base.transaction do
# Write any changes you'd like to the database.
user.update :charged_at => Time.now
card.update :charged_at => Time.now
# It's best to destroy the job in the same transaction as any other
# changes you make. Que will destroy the job for you after the run
# method if you don't do it yourself, but if your job writes to the
# DB but doesn't destroy the job in the same transaction, it's
# possible that the job could be repeated in the event of a crash.
destroy
end
end
end
See the docs on how to write a reliable job for more information on writing different types of jobs safely.
Queue your job. Again, it's best to do this in a transaction with other changes you're making. Also note that any arguments you pass will be serialized to JSON and back again, so stick to simple types (strings, integers, floats, hashes, and arrays).
ActiveRecord::Base.transaction do
# Persist credit card information
card = CreditCard.create(params[:credit_card])
ChargeCreditCard.enqueue(current_user.id, :credit_card_id => card.id)
end
You can also add options to run the job after a specific time, or with a specific priority:
# The default priority is 100, and a lower number means a higher priority. 5 would be very important.
ChargeCreditCard.enqueue current_user.id, :credit_card_id => card.id, :run_at => 1.day.from_now, :priority => 5
To determine what happens when a job is queued, you can set Que's mode in your application configuration. There are a few options for the mode:
config.que.mode = :off
- In this mode, queueing a job will simply insert it into the database - the current process will make no effort to run it. You should use this if you want to use a dedicated process to work tasks (there's a rake task to do this, see below). This is the default when running bin/rails console
.config.que.mode = :async
- In this mode, a pool of background workers is spun up, each running in their own thread. This is the default when running bin/rails server
. See the docs for more information on managing workers.config.que.mode = :sync
- In this mode, any jobs you queue will be run in the same thread, synchronously (that is, MyJob.enqueue
runs the job and won't return until it's completed). This makes your application's behavior easier to test, so it's the default in the test environment.If you're using ActiveRecord to dump your database's schema, you'll probably want to set schema_format to :sql so that Que's table structure is managed correctly.
If you want to run a worker pool in your web process and you're using a forking webserver like Phusion Passenger (in smart spawning mode), Unicorn or Puma (in some configurations), you'll want to set Que.mode = :off
in your application configuration and only start up the worker pool in the child processes after the DB connection has been reestablished.
# config/puma.rb
on_worker_boot do
ActiveRecord::Base.establish_connection
Que.mode = :async
end
# config/unicorn.rb
after_fork do |server, worker|
ActiveRecord::Base.establish_connection
Que.mode = :async
end
# config.ru
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
Que.mode = :async
end
end
end
If you're using an ORM other than ActiveRecord, you'll need to pass Que the connection manually. For instance, if you're using Sequel, you could do this after you initialize the database connection:
# config/initializers/sequel.rb
DB = Sequel.connect(ENV['DATABASE_URL'])
Que.connection = DB
If you don't want to burden your web processes with too much work and want to run workers in a background process instead, similar to how most other queues work, que-rails
provides a rake task:
# Run a pool of 4 workers:
rake que:work
# Or configure the number of workers:
QUE_WORKER_COUNT=8 rake que:work
Other options available via environment variables are QUE_QUEUE
to determine which named queue jobs are pulled from, and QUE_WAKE_INTERVAL
to determine how long workers will wait to poll again when there are no jobs available. For example, to run 2 workers that run jobs from the "other_queue" queue and wait a half-second between polls, you could do:
QUE_QUEUE=other_queue QUE_WORKER_COUNT=2 QUE_WAKE_INTERVAL=0.5 rake que:work
You can use the config.que object in your application config files to do whatever other setup you'd like. For example, you'll probably want to define an error handler, in order to pass errors raised by jobs to whatever tracking system you use:
config.que.error_handler = proc { |error| ... }
You can also manually set the number of workers in each process:
config.que.worker_count = 8
If your application code is not thread-safe, you won't want any workers to be processing jobs while anything else is happening in the Ruby process. So, you'll want to turn the worker pool off by default:
config.que.mode = :off
This will prevent Que from trying to process jobs in the background of your web processes. In order to actually work jobs, you'll want to run a single worker at a time, and to do so via a separate rake task, like so:
QUE_WORKER_COUNT=1 rake que:work
rake que:work
task and its various options.db:migrate
or routes
).git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)FAQs
Unknown package
We found that que-rails 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.