Skip to content

Commit

Permalink
Initial import of PackMule from some previous work done for Caring.com
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseppstein committed Mar 31, 2009
0 parents commit 8acef15
Show file tree
Hide file tree
Showing 7 changed files with 533 additions and 0 deletions.
46 changes: 46 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Pack Mule
=========

Pack Mule give you the facilities you need to run your code for hours or seconds in parallel across your cluster of Beanstalk workers. You can monitor the progress, coordinate tasks, and get results back when they complete.

Usage Example
-------------
We name our runner so that we can query it later. The false argument tells the runner not to
publish progress updates -- instead we'll be asking for it when we need it.

>> runner = SleepyRunner.new("this_is_an_arbitrary_name", false)
=> #<SleepyRunner:0x6444c>

First we can run the tasks in the background and block until they are done:

>> runner.run
=> 51

Or we can run it in the background:

>> task = runner.run_async
=> [1, 'localhost:11300']
The enqueue method returns a job reference which is just a tuple of a job id and a beanstalk server.

We can now ask for overall progress:

>> runner.update_progress
=> "53.0 / 101.0"

progress is returned as a string that can be eval'd to give a percentage
or you can split on " / " to get the number of jobs completed and queued.

Any instance with the same name will work:

>> SleepyRunner.new("this_is_an_arbitrary_name").update_progress
=> "59.0 / 101.0"

So we wait a while and ask for an updated progress

>> runner.update_progress
=> "101.0 / 101.0"

Now that it's finished, we can access our return value now:

>> runner.get_return_value!
=> 53
7 changes: 7 additions & 0 deletions TODO.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Things left to do for an initial release
========================================

1. Use [Moneta](http://github.com/wycats/moneta/tree/master) as an abstraction layer on top of Memcached. Any Key/Value store that all processes can access can be used -- locking is handled by elock.
2. Build an initialzier
3. Build an installer
4. Tests, tests, tests.
28 changes: 28 additions & 0 deletions examples/fibonacci_runner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Jobs::FibonacciRunner.new("fib1").fibonacci(10)
class FibonacciRunner < PackMule::Runner
def initialize(*args)
super
@record_return_values = true
end

# Be careful, this is a really good way to swamp your workers.
def fibonacci(n)
if n <= 0
0
elsif n == 1
1
elsif n == 2
3
else
# TODO: This could be optimized by recording which job is going to calculate fibonacci(n) and
# deferring to that one instead of a new one.
j1 = enqueue :fibonacci, n - 1
j2 = enqueue :fibonacci, n - 2
deferred_result :add_together, [j1, j2]
end
end

def add_together(values)
values.first + values.last
end
end
30 changes: 30 additions & 0 deletions examples/sleepy_runner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'pack_mule'

# This runner enqueue some jobs to sleep for a short time and returns the total time spent asleep.
class SleepyRunner < PackMule::Runner

def initialize(*args)
super
@record_return_values = true
end

def run_async(nap_count = 100)
enqueue :run
end

def run(nap_count = 100)
jobs = []
nap_count.times do
jobs << enqueue :snooze, rand(2)
end
deferred_result :wakeup, jobs
end

def wakeup(durations)
durations.inject(0){|total, duration| total + duration}
end

def snooze(duration)
sleep duration
end
end
1 change: 1 addition & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require File.join(File.dirname(__FILE__), 'lib', 'pack_mule')
4 changes: 4 additions & 0 deletions lib/pack_mule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module PackMule
end

require File.join(File.dirname(__FILE__), 'pack_mule', 'runner')
Loading

0 comments on commit 8acef15

Please sign in to comment.