edamame 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/LICENSE.textile +20 -0
  2. data/README.textile +90 -0
  3. data/app/edamame_san/config.ru +4 -0
  4. data/app/edamame_san/config.yml +17 -0
  5. data/app/edamame_san/edamame_san.rb +71 -0
  6. data/app/edamame_san/public/favicon.ico +0 -0
  7. data/app/edamame_san/public/images/edamame_logo.icns +0 -0
  8. data/app/edamame_san/public/images/edamame_logo.ico +0 -0
  9. data/app/edamame_san/public/images/edamame_logo.png +0 -0
  10. data/app/edamame_san/public/images/edamame_logo_2.icns +0 -0
  11. data/app/edamame_san/public/javascripts/application.js +8 -0
  12. data/app/edamame_san/public/javascripts/jquery/jquery-ui.js +8694 -0
  13. data/app/edamame_san/public/javascripts/jquery/jquery.js +4376 -0
  14. data/app/edamame_san/public/stylesheets/application.css +32 -0
  15. data/app/edamame_san/public/stylesheets/layout.css +88 -0
  16. data/app/edamame_san/views/layout.haml +13 -0
  17. data/app/edamame_san/views/load.haml +37 -0
  18. data/app/edamame_san/views/root.haml +25 -0
  19. data/bin/edamame-nuke +20 -0
  20. data/bin/edamame-ps +2 -0
  21. data/bin/edamame-stats +13 -0
  22. data/bin/edamame-sync +21 -0
  23. data/bin/edamame_util_opts.rb +10 -0
  24. data/bin/test_run.rb +14 -0
  25. data/lib/edamame.rb +29 -0
  26. data/lib/edamame/broker.rb +38 -0
  27. data/lib/edamame/job.rb +114 -0
  28. data/lib/edamame/monitoring.rb +7 -0
  29. data/lib/edamame/monitoring/README-god.textile +54 -0
  30. data/lib/edamame/monitoring/beanstalkd_god.rb +28 -0
  31. data/lib/edamame/monitoring/god_email.rb +45 -0
  32. data/lib/edamame/monitoring/god_process.rb +205 -0
  33. data/lib/edamame/monitoring/process_groups.rb +32 -0
  34. data/lib/edamame/monitoring/sinatra_god.rb +34 -0
  35. data/lib/edamame/monitoring/tyrant_god.rb +59 -0
  36. data/lib/edamame/persistent_queue.rb +152 -0
  37. data/lib/edamame/queue.rb +6 -0
  38. data/lib/edamame/queue/beanstalk.rb +134 -0
  39. data/lib/edamame/scheduling.rb +79 -0
  40. data/lib/edamame/store.rb +8 -0
  41. data/lib/edamame/store/base.rb +62 -0
  42. data/lib/edamame/store/tyrant_store.rb +49 -0
  43. data/lib/methods.txt +94 -0
  44. data/spec/edamame_spec.rb +7 -0
  45. data/spec/spec_helper.rb +10 -0
  46. data/utils/god/edamame.god +36 -0
  47. data/utils/god/edamame.yaml +61 -0
  48. data/utils/god/god-etc-init-dot-d-example +40 -0
  49. data/utils/god/god.conf +22 -0
  50. data/utils/god/god_site_config.rb +4 -0
  51. data/utils/god/wuclan.god +36 -0
  52. data/utils/simulation/Add Percent Variation.vi +0 -0
  53. data/utils/simulation/Harmonic Average.vi +0 -0
  54. data/utils/simulation/Rescheduling Simulation.aliases +3 -0
  55. data/utils/simulation/Rescheduling Simulation.lvlps +3 -0
  56. data/utils/simulation/Rescheduling Simulation.lvproj +22 -0
  57. data/utils/simulation/Rescheduling.vi +0 -0
  58. data/utils/simulation/Weighted Average.vi +0 -0
  59. metadata +147 -0
@@ -0,0 +1,94 @@
1
+ See also:
2
+
3
+ http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt
4
+
5
+ == Connection ==
6
+
7
+ connection.rb: def initialize(addr, default_tube=nil)
8
+ connection.rb: def connect
9
+ connection.rb: def close
10
+
11
+ connection.rb: def put(body, pri=65536, delay=0, ttr=120)
12
+ connection.rb: def yput(obj, pri=65536, delay=0, ttr=120)
13
+ connection.rb: def reserve(timeout=nil)
14
+ connection.rb: def delete(id)
15
+ connection.rb: def release(id, pri, delay)
16
+ connection.rb: def bury(id, pri)
17
+
18
+ connection.rb: def use(tube)
19
+ connection.rb: def watch(tube)
20
+ connection.rb: def ignore(tube)
21
+
22
+ connection.rb: def peek_job(id)
23
+ connection.rb: def peek_ready()
24
+ connection.rb: def peek_delayed()
25
+ connection.rb: def peek_buried()
26
+
27
+ connection.rb: def stats()
28
+ connection.rb: def job_stats(id)
29
+
30
+ connection.rb: def stats_tube(tube)
31
+ connection.rb: def list_tubes()
32
+ connection.rb: def list_tube_used()
33
+ connection.rb: def list_tubes_watched(cached=false)
34
+
35
+ == Pool ==
36
+
37
+ connection.rb: def initialize(addrs, default_tube=nil)
38
+ connection.rb: def connect()
39
+ connection.rb: def open_connections()
40
+ connection.rb: def last_server
41
+ connection.rb: def put(body, pri=65536, delay=0, ttr=120)
42
+ connection.rb: def yput(obj, pri=65536, delay=0, ttr=120)
43
+ connection.rb: def reserve(timeout=nil)
44
+ connection.rb: def use(tube)
45
+ connection.rb: def watch(tube)
46
+ connection.rb: def ignore(tube)
47
+ connection.rb: def raw_stats()
48
+ connection.rb: def stats()
49
+ connection.rb: def raw_stats_tube(tube)
50
+ connection.rb: def stats_tube(tube)
51
+ connection.rb: def list_tubes()
52
+ connection.rb: def list_tube_used()
53
+ connection.rb: def list_tubes_watched(*args)
54
+ connection.rb: def remove(conn)
55
+ connection.rb: def close
56
+ connection.rb: def peek_ready()
57
+ connection.rb: def peek_delayed()
58
+ connection.rb: def peek_buried()
59
+ connection.rb: def peek_job(id)
60
+ connection.rb: def call_wrap(c, *args)
61
+ connection.rb: def retry_wrap(*args)
62
+ connection.rb: def send_to_each_conn_first_res(*args)
63
+ connection.rb: def send_to_rand_conn(*args)
64
+ connection.rb: def send_to_all_conns(*args)
65
+ connection.rb: def pick_connection()
66
+ connection.rb: def make_hash(pairs)
67
+ connection.rb: def map_hash(h)
68
+ connection.rb: def compact_hash(hash)
69
+ connection.rb: def sum_hashes(hs)
70
+ connection.rb: def combine_stats(k, a, b)
71
+
72
+
73
+ == Job ==
74
+
75
+ job.rb: def [](name)
76
+ job.rb: def []=(name, val)
77
+ job.rb: def ybody()
78
+ job.rb: def initialize(conn, id, body)
79
+ job.rb: def delete()
80
+ job.rb: def put_back(pri=self.pri, delay=0, ttr=self.ttr)
81
+ job.rb: def release(newpri=pri, delay=0)
82
+ job.rb: def bury(newpri=pri)
83
+ job.rb: def stats()
84
+ job.rb: def timeouts() stats['timeouts'] end
85
+ job.rb: def time_left() stats['time-left'] end
86
+ job.rb: def age() stats['age'] end
87
+ job.rb: def state() stats['state'] end
88
+ job.rb: def delay() stats['delay'] end
89
+ job.rb: def pri() stats['pri'] end
90
+ job.rb: def ttr() stats['ttr'] end
91
+ job.rb: def server()
92
+ job.rb: def decay(d=([1, delay].max * 1.3).ceil)
93
+ job.rb: def to_s
94
+ job.rb: def inspect
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Edamame" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'edamame'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
@@ -0,0 +1,36 @@
1
+ $: << File.dirname(__FILE__)+'/../../lib'
2
+ $: << File.dirname(__FILE__)+'/../../../wukong/lib'
3
+ $: << File.dirname(__FILE__)+'/../../../monkeyshines/lib'
4
+ require 'edamame'
5
+ require 'edamame/monitoring'
6
+
7
+ #
8
+ # For debugging:
9
+ #
10
+ # sudo god -c /Users/flip/ics/edamame/utils/god/edamame.god -D
11
+ #
12
+ # (for production, use the etc/initc.d script in this directory)
13
+ #
14
+ # TODO: define an EdamameDirector that lets us name these collections.
15
+ #
16
+
17
+ GodProcess::GLOBAL_SITE_OPTIONS_FILES << ENV['HOME']+'/.edamame'
18
+
19
+ # #
20
+ # # Twitter
21
+ # #
22
+ # handle = 'twitter'
23
+ # God.process_group 11250, [
24
+ # # [ BeanstalkdGod, { :max_mem_usage => 100.megabytes } ],
25
+ # # [ TyrantGod, { :db_name => handle+'-queue.tct' } ],
26
+ # # [ TyrantGod, { :db_name => handle+'-scraped_at.tch' } ],
27
+ # [ SinatraGod, { :thin_config_yml => '/slice/www/webshines/current/config.yml' } ],
28
+ # ]
29
+
30
+ GodProcess.global_site_options[:process_groups].each do |handle, group_info|
31
+ group_info.each do |group, group_options|
32
+ klass = FactoryModule.get_class Kernel, group_options[:type]
33
+ klass.create(group_options)
34
+ end
35
+ end
36
+
@@ -0,0 +1,61 @@
1
+ --- # -*- YAML -*-
2
+ #
3
+ # Save this file in your god dir, *then* change the settings below.
4
+ # Make sure your version control system is set to ignore the file.
5
+ #
6
+
7
+ :god_notifiers:
8
+ :domain: infochimps.org #
9
+ :username: robot@infochimps.org # sender email username
10
+ :password: xx_password_xx # sender email password
11
+ :to: flip@infochimps.org # recipient email address
12
+ :to_name: Monitors # recipient name
13
+
14
+ # these apply to all processes
15
+ :god_process:
16
+ :flapping_notify: default
17
+
18
+ :tyrant_god:
19
+ :db_dirname: /data/distdb
20
+
21
+ :sinatra_god:
22
+ :thin_config_yml: '/slice/www/webshines/current/config.yml'
23
+ :server_exe: '/usr/local/bin/thin'
24
+
25
+
26
+ :process_groups:
27
+ :lastfm:
28
+ :queue_beanstalkd:
29
+ :type: :beanstalkd_god
30
+ :max_mem_usage: 100000000
31
+ :port: 11250
32
+ :queue_db:
33
+ :type: :tyrant_god
34
+ :db_name: lastfm-queue.tct
35
+ :port: 11251
36
+ :scraped_at_db:
37
+ :type: :tyrant_god
38
+ :db_name: lastfm-scraped_at.tch
39
+ :port: 11252
40
+
41
+ :twitter_search:
42
+ :queue_beanstalkd:
43
+ :type: :beanstalkd_god
44
+ :max_mem_usage: 100000000
45
+ :port: 11260
46
+ :queue_db:
47
+ :type: :tyrant_god
48
+ :db_name: twitter_search-queue.tct
49
+ :port: 11261
50
+
51
+ :twitter_api:
52
+ :scraped_at_db:
53
+ :type: :tyrant_god
54
+ :db_name: twitter_api-scraped_at.tch
55
+ :port: 11272
56
+ # :web_monitor:
57
+ # :type: :sinatra_god
58
+ # :thin_config_yml: /slice/www/webshines/current/config.yml
59
+ # :port: 11275
60
+ # :pid_file: /var/run/god/thin.pid
61
+
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ #
3
+ # God
4
+ #
5
+ # chkconfig: - 85 15
6
+ # description: start, stop, restart God (bet you feel powerful)
7
+ #
8
+ #
9
+ # Make this go with
10
+ # chmod +x /etc/init.d/god
11
+ # /usr/sbin/update-rc.d god defaults
12
+
13
+ RETVAL=0
14
+
15
+ case "$1" in
16
+ start)
17
+ /usr/bin/god -P /var/run/god.pid -l /var/log/god.log
18
+ /usr/bin/god load /etc/god.conf
19
+ RETVAL=$?
20
+ ;;
21
+ stop)
22
+ kill `cat /var/run/god.pid`
23
+ RETVAL=$?
24
+ ;;
25
+ restart)
26
+ kill `cat /var/run/god.pid`
27
+ /usr/bin/god -P /var/run/god.pid -l /var/log/god.log
28
+ /usr/bin/god load /etc/god.conf
29
+ RETVAL=$?
30
+ ;;
31
+ status)
32
+ RETVAL=$?
33
+ ;;
34
+ *)
35
+ echo "Usage: god {start|stop|restart|status}"
36
+ exit 1
37
+ ;;
38
+ esac
39
+
40
+ exit $RETVAL
@@ -0,0 +1,22 @@
1
+ # load in all god configs
2
+ $: << '/home/flip/ics/edamame/lib'
3
+ $: << '/home/flip/ics/wukong/lib'
4
+ require 'yaml'
5
+ require 'extlib'
6
+ require 'wukong/extensions/hash'
7
+
8
+ require "edamame/monitoring"
9
+ GodProcess::GLOBAL_SITE_OPTIONS_FILES << '/slice/etc/god/.edamame'
10
+ TyrantGod::DEFAULT_OPTIONS[:db_dirname] = '/data/distdb'
11
+
12
+ p GodProcess.global_site_options,
13
+ TyrantGod.site_options, TyrantGod.default_options.deep_merge(TyrantGod.site_options),
14
+ GodProcess.site_options
15
+
16
+ #
17
+ # Define email notifiers and attach one by default
18
+ #
19
+ God.setup_email GodProcess.global_site_options[:email]
20
+ GodProcess::DEFAULT_OPTIONS[:flapping_notify] = 'default'
21
+
22
+ God.load "/slice/etc/god/*.god"
@@ -0,0 +1,4 @@
1
+ require 'yaml'
2
+ SITE_OPTIONS_FILE = ENV['HOME']+'/.monkeyshines'
3
+ SITE_OPTIONS = YAML.load(File.open(SITE_OPTIONS_FILE))
4
+ God.setup_email SITE_OPTIONS[:email]
@@ -0,0 +1,36 @@
1
+ #
2
+ # For debugging:
3
+ #
4
+ # sudo god -c /Users/flip/ics/edamame/utils/god/edamame.god -D
5
+ #
6
+ # (for production, use the etc/initc.d script in this directory)
7
+ #
8
+ # TODO: define an EdamameDirector that lets us name these collections.
9
+ #
10
+
11
+ #
12
+ # Twitter Search
13
+ #
14
+ handle = 'twitter_search'
15
+ base_port = 11220
16
+ BeanstalkdGod.create :port => base_port + 0, :max_mem_usage => 100.megabytes
17
+ TyrantGod.create :port => base_port + 1, :db_name => handle+'-queue.tct', :db_dirname => '/data/ripd/com.tw/com.twitter.search/distdb/20090928'
18
+
19
+ #
20
+ # Lastfm
21
+ #
22
+ handle = 'lastfm'
23
+ base_port = 11240
24
+ BeanstalkdGod.create :port => base_port + 0, :max_mem_usage => 2.gigabytes
25
+ TyrantGod.create :port => base_port + 1, :db_name => handle+'-queue.tct', :db_dirname => '/data/ripd/com.au/com.audioscrobbler.com/distdb/20090928'
26
+ TyrantGod.create :port => base_port + 2, :db_name => handle+'-scraped_at.tch', :db_dirname => '/data/ripd/com.au/com.audioscrobbler.com/distdb/20090928'
27
+
28
+ # #
29
+ # # Facebook
30
+ # #
31
+ # handle = 'facebook'
32
+ # base_port = 11250
33
+ # BeanstalkdGod.create :port => base_port + 0, :max_mem_usage => 100.megabytes
34
+ # TyrantGod.create :port => base_port + 1, :db_name => handle+'-queue.tct'
35
+ # TyrantGod.create :port => base_port + 2, :db_name => handle+'-scraped_at.tch'
36
+ # TyrantGod.create :port => base_port + 3, :db_name => handle+'-registration.tch'
@@ -0,0 +1,3 @@
1
+ [My Computer]
2
+ My Computer = "192.168.69.129"
3
+
@@ -0,0 +1,3 @@
1
+ [ProjectWindow_Data]
2
+ ProjectExplorer.ClassicPosition[String] = "52,33,416,383"
3
+
@@ -0,0 +1,22 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <Project Type="Project" LVVersion="8608001">
3
+ <Item Name="My Computer" Type="My Computer">
4
+ <Property Name="server.app.propertiesEnabled" Type="Bool">true</Property>
5
+ <Property Name="server.control.propertiesEnabled" Type="Bool">true</Property>
6
+ <Property Name="server.tcp.enabled" Type="Bool">false</Property>
7
+ <Property Name="server.tcp.port" Type="Int">0</Property>
8
+ <Property Name="server.tcp.serviceName" Type="Str">My Computer/VI Server</Property>
9
+ <Property Name="server.tcp.serviceName.default" Type="Str">My Computer/VI Server</Property>
10
+ <Property Name="server.vi.callsEnabled" Type="Bool">true</Property>
11
+ <Property Name="server.vi.propertiesEnabled" Type="Bool">true</Property>
12
+ <Property Name="specify.custom.address" Type="Bool">false</Property>
13
+ <Item Name="Rescheduling.vi" Type="VI" URL="../Rescheduling.vi"/>
14
+ <Item Name="Weighted Average.vi" Type="VI" URL="../Weighted Average.vi"/>
15
+ <Item Name="Harmonic Average.vi" Type="VI" URL="../Harmonic Average.vi"/>
16
+ <Item Name="Add Percent Variation.vi" Type="VI" URL="../Add Percent Variation.vi"/>
17
+ <Item Name="Rescheduling with revisit.vi" Type="VI" URL="../Rescheduling with revisit.vi"/>
18
+ <Item Name="Rescheduling with revisit 2.vi" Type="VI" URL="../Rescheduling with revisit 2.vi"/>
19
+ <Item Name="Dependencies" Type="Dependencies"/>
20
+ <Item Name="Build Specifications" Type="Build"/>
21
+ </Item>
22
+ </Project>
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: edamame
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Philip (flip) Kromer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-12 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: beanstalk-client
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: wukong
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: monkeyshines
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: "Edamame combines the Beanstalk priority queue with a Tokyo Tyrant database and God monitoring to produce a persistent distributed priority job queue system. \n\n\
46
+ Like beanstalk, it is fast, lightweight, distributed, priority queuing, reliable scheduling; it adds persistence, named jobs and job querying/enumeration. "
47
+ email: flip@infochimps.org
48
+ executables:
49
+ - edamame-nuke
50
+ - edamame-ps
51
+ - edamame-stats
52
+ - edamame-sync
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - LICENSE.textile
57
+ - README.textile
58
+ files:
59
+ - LICENSE.textile
60
+ - README.textile
61
+ - app/edamame_san/config.ru
62
+ - app/edamame_san/config.yml
63
+ - app/edamame_san/edamame_san.rb
64
+ - app/edamame_san/public/favicon.ico
65
+ - app/edamame_san/public/images/edamame_logo.icns
66
+ - app/edamame_san/public/images/edamame_logo.ico
67
+ - app/edamame_san/public/images/edamame_logo.png
68
+ - app/edamame_san/public/images/edamame_logo_2.icns
69
+ - app/edamame_san/public/javascripts/application.js
70
+ - app/edamame_san/public/javascripts/jquery/jquery-ui.js
71
+ - app/edamame_san/public/javascripts/jquery/jquery.js
72
+ - app/edamame_san/public/stylesheets/application.css
73
+ - app/edamame_san/public/stylesheets/layout.css
74
+ - app/edamame_san/views/layout.haml
75
+ - app/edamame_san/views/load.haml
76
+ - app/edamame_san/views/root.haml
77
+ - bin/edamame-nuke
78
+ - bin/edamame-ps
79
+ - bin/edamame-stats
80
+ - bin/edamame-sync
81
+ - bin/edamame_util_opts.rb
82
+ - bin/test_run.rb
83
+ - lib/edamame.rb
84
+ - lib/edamame/broker.rb
85
+ - lib/edamame/job.rb
86
+ - lib/edamame/monitoring.rb
87
+ - lib/edamame/monitoring/README-god.textile
88
+ - lib/edamame/monitoring/beanstalkd_god.rb
89
+ - lib/edamame/monitoring/god_email.rb
90
+ - lib/edamame/monitoring/god_process.rb
91
+ - lib/edamame/monitoring/process_groups.rb
92
+ - lib/edamame/monitoring/sinatra_god.rb
93
+ - lib/edamame/monitoring/tyrant_god.rb
94
+ - lib/edamame/persistent_queue.rb
95
+ - lib/edamame/queue.rb
96
+ - lib/edamame/queue/beanstalk.rb
97
+ - lib/edamame/scheduling.rb
98
+ - lib/edamame/store.rb
99
+ - lib/edamame/store/base.rb
100
+ - lib/edamame/store/tyrant_store.rb
101
+ - lib/methods.txt
102
+ - spec/edamame_spec.rb
103
+ - spec/spec_helper.rb
104
+ - utils/god/edamame.god
105
+ - utils/god/edamame.yaml
106
+ - utils/god/god-etc-init-dot-d-example
107
+ - utils/god/god.conf
108
+ - utils/god/god_site_config.rb
109
+ - utils/god/wuclan.god
110
+ - utils/simulation/Add Percent Variation.vi
111
+ - utils/simulation/Harmonic Average.vi
112
+ - utils/simulation/Rescheduling Simulation.aliases
113
+ - utils/simulation/Rescheduling Simulation.lvlps
114
+ - utils/simulation/Rescheduling Simulation.lvproj
115
+ - utils/simulation/Rescheduling.vi
116
+ - utils/simulation/Weighted Average.vi
117
+ has_rdoc: true
118
+ homepage: http://github.com/mrflip/edamame
119
+ licenses: []
120
+
121
+ post_install_message:
122
+ rdoc_options:
123
+ - --charset=UTF-8
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: "0"
131
+ version:
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: "0"
137
+ version:
138
+ requirements: []
139
+
140
+ rubyforge_project:
141
+ rubygems_version: 1.3.5
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Beanstalk + Tokyo Tyrant = Edamame, a fast persistent distributed priority job queue.
145
+ test_files:
146
+ - spec/edamame_spec.rb
147
+ - spec/spec_helper.rb