
Security News
New Website “Is It Really FOSS?” Tracks Transparency in Open Source Distribution Models
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Timberline is a dead-simple queuing service written in Ruby and backed by Redis. It makes a few assumptions about how you'd like to handle your queues and what kind of issues you might be dealing with:
Timberline assumes that you want to be able to programmatically retry some failed jobs, and that you want to keep track of jobs that totally errored out so that you can try them again.
Timberline assumes that you want to queue data, and not actions. You can have one app that puts data onto the queue and another app that reads data from the queue, and the only thing they have to have in common (aside from knowing what the data means) is that they both include Timberline.
Timberline assumes that it's preferable, if not important to you, to process jobs as fast as you possibly can. To that end, Timberline uses blocking reads in Redis to pull jobs off of the queue as soon as they're available.
Documentation for Timberline is available on rubydoc.info here. The code itself is documented with YARD.
Sounds SOAPy, I know. The envelope is a simple object that wraps the data you want to put on the queue - it's responsible for tracking things like the job ID, the queue it was put on, how many times it's been retried, etc., etc. It's also accessible to both the queue processor and whatever is putting jobs on the queue, so if you want to be able to check in on the administrative details (or add some of your own) this is a great place to do it instead of muddying up the meat of your message.
Processing items on a Timberline queue is handled by Workers. A Worker can be created as simply as providing a block that executes on job items, or you can write your own Workers that perform special functionality.
Sometimes jobs just fail because of something that was outside of your control. Maybe there was a glitch and your HTTP connection to PayPal didn't go through, or maybe Github is down right now, or... whatever. In these situations it makes sense to re-queue jobs and let them retry - just don't let them do it forever or they may never leave. Timberline is designed to make retrying jobs in these circumstances super-easy.
On the other hand, sometimes your jobs deserved to fail. Maybe there was a bug in your processor code, or maybe a user was able to sneak bad data past you. In any event, Timberline maintains an error queue where jobs go when they're explicitly marked as bad jobs, or when they've been retried the maximum number of times. You can then check the jobs out and resubmit them to their original queue after you fix the issue.
Timberline is designed to be as easy to work with as possible, and operates almost like a DSL for interacting with stuff on the queue.
There are a few things that you probably want to be able to configure in Timberline. At the moment this is largely stuff related to the redis server connection, but you can also configure a namespace for your redis queues (defaults to "timberline") and a maximum number of retry attempts for jobs in the queue (more on that later). There are 3 ways to configure Timberline:
The most direct way is to configure Timberline via ruby code as follows:
Timberline.configure do |c|
c.database = 1
c.host = "192.168.1.105"
c.port = 12345
c.password = "foobar"
end
...As long as you run this block before you attempt to access your queues, your settings will all take effect. Redis defaults will be used if you omit anything.
If you prefer a static config file, you can write a YAML file like the following:
database: 1
host: 192.168.1.105
port: 12345
password: foobar
...and then use the TIMBERLINE_YAML
constant to specify the file's location:
TIMBERLINE_YAML = 'path/to/your/yaml/file.yaml'
3. Running on Heroku? Define an environment variable for the URL:
export TIMBERLINE_URL="redis://:foobar@192.168.1.105:12345/1?timeout=99&namespace=my_namespace"
To push a job onto the queue you'll want to make use of the Timberline#push
method, like so:
Timberline.push "queue_name", data, { other_data: some_stuff }
queue_name
is the name of the queue you want to push data onto; data is the
data you want to push onto the queue (remember that this all gets converted to
JSON, so you probably want to stick to things that represent well as strings),
and the optional third argument is a hash of any extra parameters you want to
include in the job's envelope.
Reading from a queue is pretty simple in Timberline. You can simply write something like the following:
Timberline.watch "queue_name" do |job|
begin
puts job.other_data
doSomethingWithThisStuff(job.contents)
rescue SomeTransientError
retry_job(job)
rescue SomeFatalError
error_job(job)
end
end
You will, in all likelihood, be writing more complicated stuff than this, of course. But you call Timberline.watch and provide it with a queue name and a block that will be called for each job as Timberline reads them off of the queue. Things to note:
Each queue has its own error queue, accessible through Queue#error_queue
.
You can pop items directly off of the queue to operate on them if you want, or
you could write a queue processor that reads off of that queue.
In order to make reading off of the queue easier, there's a binary named
timberline
included with this gem.
Example:
# timberline_sample.rb
TIMBERLINE_YAML = "timberline_sample.yaml"
watch "sample_queue" do |job|
puts job.contents
end
The above file, when executed via timberline timberline_sample.rb
, will print out
the value of any object put on the queue. If no objects are on the queue it will
block until either the process is killed, or until something is added to the
queue.
There are some options to the Timberline binary that you may find helpful -
timberline --help
for more.
If you're using Timberline in conjunction with a Rails environment, check out the timberline-rails gem.
The Redis client (>= v3.2) is able to perform automatic Redis connection failovers by using Redis Sentinel. In cases where this is enabled, pass sentinel configuration on to the Redis client using the "sentinels" key a configuration:
Via timberline.yml:
host: 127.0.0.1
sentinels:
- host: 127.0.0.1
port: 26379
Via the Timberline.configure:
Timberline.configure do |c|
# ...
c.sentinels = [{ host: 127.0.0.1, port: 26379 }]
end
Via the ENV VAR
export TIMBERLINE_URL="redis://:foobar@192.168.1.105:12345/1?sentinel=host1:1111&sentinel=host2:2222"
Still to be done:
Stuff that would be cool but isn't quite on the radar yet:
If Timberline interests you and you think you might want to contribute, hit me up over Github. You can also just fork it and make some changes, but there's a better chance that your work won't be duplicated or rendered obsolete if you check in on the current development status first.
You need Redis installed to do development on Timberline, and currently the test suites assume that you're using the default configurations for Redis. That should probably change, but it probably won't until someone needs it to.
Gem requirements/etc. should be handled by Bundler.
Copyright (C) 2014 by Tommy Morgan
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
FAQs
Unknown package
We found that timberline 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
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.