beanstalkd_view 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 1.1.0
2
+ -----------
3
+
4
+ - Switched from beanstalk-client to beaneater gem
5
+
6
+
1
7
  1.0.2
2
8
  -----------
3
9
 
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ #gem 'beaneater', :git => 'https://github.com/beanstalkd/beaneater.git'
4
+
3
5
  # Specify your gem's dependencies in beanstalkd_view.gemspec
4
6
  gemspec
5
7
 
data/README.md CHANGED
@@ -10,7 +10,6 @@ Configuration
10
10
  To use in a Rails app, include the gem in your Gemfile:
11
11
 
12
12
  ``` ruby
13
- gem 'beanstalk-client', :git => 'https://github.com/kr/beanstalk-client-ruby.git' #Use the latest, if you need the pause-tube command
14
13
  gem beanstalkd_view
15
14
  ```
16
15
 
@@ -23,7 +22,7 @@ Use the following environment variable to specify the location of the beanstalk
23
22
  ENV['BEANSTALK_URL'] = 'beanstalk://localhost/'
24
23
  ```
25
24
 
26
- (This can be a comma separated list.)
25
+ This can be a comma separated list, e.g. 'beanstalk://localhost:11300,beanstalk://localhost:11400'
27
26
 
28
27
  Embedding in a Rails app
29
28
  ------------------------
@@ -63,12 +62,22 @@ bundle exec beanstalkd_view
63
62
 
64
63
  (This will use the vegas gem to launch the Sinatra app on an available port.)
65
64
 
66
- Alternatively, a Rackup file is provided. To use: cd into the beanstalkd_view directory and execute the rackup command.
65
+ Alternatively, a Rackup file is provided. To use: cd into the beanstalkd_view directory and execute:
66
+
67
+ rackup
68
+
67
69
 
68
70
  Screenshot
69
71
  ------------------------
70
72
  ![Screenshot](http://s16.postimage.org/4mdum0x79/i_OS_Simulator_Screen_shot_Apr_24_2012_10_29_33.png)
71
73
 
74
+ Running the tests
75
+ ------------------------
76
+ There are 3 variants of RSpec tests.
77
+ * Without beanstalkd running, just execute: rspec spec
78
+ * Without 1 instance of beanstalkd running (default port), execute: rspec spec --tag requires_beanstalkd
79
+ * Without 2 instances of beanstalkd running (ports 11300 and 11400), execute: rspec spec --tag requires_two_beanstalkd
80
+
72
81
  License
73
82
  ------------------------
74
83
 
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ RSpec::Core::RakeTask.new(:spec)
10
10
 
11
11
  task :default => :spec
12
12
 
13
- require 'beanstalk-client'
13
+ require 'beaneater'
14
14
  require 'json'
15
15
 
16
16
  namespace :beanstalkd_view do
@@ -21,17 +21,17 @@ namespace :beanstalkd_view do
21
21
  task :enqueue_test do
22
22
  host = "localhost"
23
23
  port = 11300
24
- beanstalk = Beanstalk::Pool.new([ "#{host}:#{port}" ])
24
+ beanstalk = Beaneater::Pool.new([ "#{host}:#{port}" ])
25
25
 
26
26
  # Loop flooding the queues with jobs
27
27
  while true
28
- tube = TEST_QUEUES.sample
28
+ tube_name = TEST_QUEUES.sample
29
29
  pri = 65536
30
30
  delay = 0
31
31
  ttr = 120
32
- beanstalk.use tube
33
- beanstalk.put [ tube, {} ].to_json, pri, delay, ttr
34
- puts "Enqueued Job to #{tube}"
32
+ tube = beanstalk.tubes[tube_name]
33
+ tube.put '{}', :pri => pri, :delay => delay, :ttr => ttr
34
+ puts "Enqueued Job to #{tube_name}"
35
35
  end
36
36
  end
37
37
 
@@ -39,14 +39,20 @@ namespace :beanstalkd_view do
39
39
  task :pull_test do
40
40
  host = "localhost"
41
41
  port = 11300
42
- beanstalk = Beanstalk::Pool.new([ "#{host}:#{port}" ])
42
+ beanstalk = Beaneater::Pool.new([ "#{host}:#{port}" ])
43
43
 
44
44
  while true
45
- tube = TEST_QUEUES.sample
46
- beanstalk.watch(tube)
47
- job = beanstalk.reserve
48
- puts "Pulled Job #{job} from #{tube}"
49
- job.delete
45
+ tube_name = TEST_QUEUES.sample
46
+ begin
47
+ beanstalk.tubes.watch!(tube_name)
48
+ job = beanstalk.tubes.reserve(1)
49
+ if job
50
+ puts "Pulled Job #{job} from #{tube_name}"
51
+ job.delete
52
+ end
53
+ rescue Exception => ex
54
+ puts "Exception while pulling job from #{tube_name}: #{ex}"
55
+ end
50
56
  end
51
57
  end
52
58
 
@@ -2,10 +2,12 @@ module BeanstalkdView
2
2
 
3
3
  module BeanstalkdUtils
4
4
 
5
+ GUESS_PEEK_RANGE = 100 # Default number of elements to use in peek-range guesses
6
+
5
7
  class BadURL < RuntimeError; end
6
8
 
7
9
  def beanstalk
8
- @@beanstalk ||= Beanstalk::Pool.new(beanstalk_addresses)
10
+ @@beanstalk ||= Beaneater::Pool.new(beanstalk_addresses)
9
11
  end
10
12
 
11
13
  def beanstalk_url
@@ -13,8 +15,6 @@ module BeanstalkdView
13
15
  ENV['BEANSTALK_URL'] || 'beanstalk://localhost/'
14
16
  end
15
17
 
16
- class BadURL < RuntimeError; end
17
-
18
18
  def beanstalk_addresses
19
19
  uris = beanstalk_url.split(/[\s,]+/)
20
20
  uris.map {|uri| beanstalk_host_and_port(uri)}
@@ -25,5 +25,67 @@ module BeanstalkdView
25
25
  raise(BadURL, uri_string) if uri.scheme != 'beanstalk'
26
26
  "#{uri.host}:#{uri.port || 11300}"
27
27
  end
28
+
29
+ # Convert Beaneater::Job to hash
30
+ def job_to_hash(job)
31
+ ret_value = {}
32
+ job_stats = job.stats
33
+ job_stats.keys.each { |key| ret_value[key] = job_stats[key] }
34
+ ret_value['body'] = job.body.inspect
35
+ ret_value
36
+ end
37
+
38
+ # Return the stats data in a format for the Bluff JS UI Charts
39
+ def get_chart_data_hash(tubes)
40
+ chart_data = {}
41
+ chart_data["total_jobs_data"] = Hash.new
42
+ chart_data["buried_jobs_data"] = Hash.new
43
+ chart_data["total_jobs_data"]["items"] = Array.new
44
+ chart_data["buried_jobs_data"]["items"] = Array.new
45
+ tubes.each do |tube|
46
+ stats = tube.stats
47
+ #total_jobs
48
+ total_jobs = stats[:total_jobs]
49
+ if total_jobs > 0
50
+ total_datum = {}
51
+ total_datum["label"] = tube.name
52
+ total_datum["data"] = total_jobs
53
+ chart_data["total_jobs_data"]["items"] << total_datum
54
+ end
55
+ #buried_jobs
56
+ buried_jobs = stats[:current_jobs_buried]
57
+ if buried_jobs > 0
58
+ buried_datum = {}
59
+ buried_datum["label"] = tube.name
60
+ buried_datum["data"] = buried_jobs
61
+ chart_data["buried_jobs_data"]["items"] << buried_datum
62
+ end
63
+ end
64
+ chart_data
65
+ end
66
+
67
+ # Pick a Minimum Peek Range Based on minumum ready jobs on all tubes
68
+ def guess_min_peek_range(tubes)
69
+ min = 0
70
+ tubes.each do |tube|
71
+ response = tube.peek('ready')
72
+ if response
73
+ if min == 0
74
+ min = response.id.to_i
75
+ else
76
+ min = [min, response.id.to_i].min
77
+ end
78
+ end
79
+ end
80
+ # Add some jitter in the opposite direction of 1/4 range
81
+ jitter_min = (min-(GUESS_PEEK_RANGE*0.25)).to_i
82
+ [1, jitter_min].max
83
+ end
84
+
85
+ # Pick a Minimum Peek Range Based on the minimum
86
+ def guess_max_peek_range(min)
87
+ (min+GUESS_PEEK_RANGE)-1
88
+ end
89
+
28
90
  end
29
91
  end
@@ -85,10 +85,11 @@ $(document).ready(function() {
85
85
  } else {
86
86
  // Build the confirmation popup
87
87
  data = {};
88
+ data["tube"] = tube;
88
89
  data["pri"] = priority;
89
90
  data["delay"] = delay;
90
91
  data["ttr"] = ttr;
91
- data["body"] = JSON.stringify([tube, parsed_body_json]);
92
+ data["body"] = JSON.stringify(parsed_body_json);
92
93
  $("#job_info_popup_title").html(create_new_job_title());
93
94
  $("#job_info_popup_body").html(create_job_info_table(data));
94
95
  $("#job_info_popup_footer").html(create_new_job_buttons());
@@ -127,6 +128,7 @@ $(document).ready(function() {
127
128
  function create_job_info_table(data) {
128
129
  var job_info_table = "<table class=\"table\">";
129
130
  job_info_table += "<tbody>";
131
+ job_info_table += create_job_info_row("tube", data["tube"], "The tube to which the job will be added.");
130
132
  job_info_table += create_job_info_row("pri", data["pri"], "The priority value set by the put, release, or bury commands.");
131
133
  if ("age" in data) {
132
134
  job_info_table += create_job_info_row("age", data["age"], "The time in seconds since the put command that created this job.");
@@ -3,10 +3,10 @@ $(document).ready(function() {
3
3
  function filter_table_by_tube() {
4
4
  var tube = $("#peek_range_tube_select").val();
5
5
  if (tube === '') {
6
- $('tr[data-tube]').show();
6
+ $('tr.datum[data-tube]').show();
7
7
  } else {
8
- $('tr[data-tube!="'+tube+'"]').hide();
9
- $('tr[data-tube="'+tube+'"]').show();
8
+ $('tr.datum[data-tube!="'+tube+'"]').hide();
9
+ $('tr.datum[data-tube="'+tube+'"]').show();
10
10
  }
11
11
  }
12
12
 
@@ -30,19 +30,17 @@ module BeanstalkdView
30
30
  '/css/vendor/bootstrap.min.css',
31
31
  '/css/app.css']
32
32
  end
33
-
34
- GUESS_PEEK_RANGE = 100 # Default number of elements to use in peek-range guesses
35
-
33
+
36
34
  get "/" do
37
35
  begin
38
- @tubes = beanstalk.list_tubes
36
+ @connections = beanstalk.connections
37
+ @tubes = beanstalk.tubes.all
39
38
  @stats = beanstalk.stats
40
- @tube_set = tube_set(@tubes)
41
- chart_data = get_chart_data_hash(@tube_set)
39
+ chart_data = get_chart_data_hash(@tubes)
42
40
  @total_jobs_data = chart_data["total_jobs_data"]
43
41
  @buried_jobs_data = chart_data["buried_jobs_data"] if chart_data["buried_jobs_data"]["items"].size > 0
44
42
  erb :index
45
- rescue Beanstalk::NotConnected => @error
43
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
46
44
  erb :error
47
45
  end
48
46
  end
@@ -50,28 +48,27 @@ module BeanstalkdView
50
48
  post "/add_job" do
51
49
  begin
52
50
  response = nil
53
- body = JSON.parse(params[:body])
54
- beanstalk.on_tube(params[:tube]) do |conn|
55
- response = conn.put([ params[:tube], body ].to_json, params[:priority].to_i, params[:delay].to_i, params[:ttr].to_i)
56
- end
51
+ tube = beanstalk.tubes[params[:tube]]
52
+ response = tube.put params[:body],
53
+ :pri => params[:priority].to_i, :delay => params[:delay].to_i, :ttr => params[:ttr].to_i
57
54
  if response
58
- cookies[:beanstalkd_view_notice] = "Added job #{response.inspect}"
55
+ cookies[:beanstalkd_view_notice] = "Added job: #{response.inspect}"
59
56
  redirect url("/")
60
57
  else
61
58
  cookies[:beanstalkd_view_notice] = "Error adding job"
62
59
  redirect url("/")
63
60
  end
64
- rescue Beanstalk::NotConnected => @error
61
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
65
62
  erb :error
66
63
  end
67
64
  end
68
65
 
69
66
  get "/tube/:tube" do
70
67
  begin
71
- @tube = params[:tube]
72
- @stats = beanstalk.stats_tube(@tube)
68
+ @tube = beanstalk.tubes[params[:tube]]
69
+ @stats = @tube.stats
73
70
  erb :tube_stats
74
- rescue Beanstalk::NotConnected => @error
71
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
75
72
  erb :error
76
73
  end
77
74
  end
@@ -79,24 +76,14 @@ module BeanstalkdView
79
76
  get "/peek/:tube/:type" do
80
77
  content_type :json
81
78
  begin
82
- response = nil
83
- beanstalk.on_tube(params[:tube]) do |conn|
84
- if (params[:type]) == "ready"
85
- response = conn.peek_ready()
86
- elsif (params[:type]) == "delayed"
87
- response = conn.peek_delayed()
88
- else
89
- response = conn.peek_buried()
90
- end
91
- end
79
+ tube = beanstalk.tubes[params[:tube]]
80
+ response = tube.peek(params[:type])
92
81
  if response
93
- ret_value = response.stats
94
- ret_value["body"] = response.body
95
- ret_value.to_json
82
+ job_to_hash(response).to_json
96
83
  else
97
84
  { :error => "No job was found, or an error occurred while trying to peek at the next job."}.to_json
98
85
  end
99
- rescue Beanstalk::NotConnected => @error
86
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
100
87
  { :error => @error.to_s }.to_json
101
88
  end
102
89
  end
@@ -105,15 +92,15 @@ module BeanstalkdView
105
92
  begin
106
93
  @min = params[:min].to_i
107
94
  @max = params[:max].to_i
108
- @tube = params[:tube]
95
+ @min = params[:min].to_i
96
+ tubes = beanstalk.tubes
97
+ @tubes = tubes.all
98
+ @tube = tubes[params[:tube]] if params[:tube] and params[:tube] != ''
109
99
 
110
- # Get the Set of Tubes for the Form
111
- tubes = beanstalk.list_tubes
112
- @tube_set = tube_set(tubes)
113
100
  # Only guess with the specified tube (if passed in)
114
- guess_tubes = @tube_set
115
- if @tube and not @tube.empty?
116
- guess_tubes = Set.new
101
+ guess_tubes = @tubes
102
+ if @tube
103
+ guess_tubes = []
117
104
  guess_tubes << @tube
118
105
  end
119
106
  # Guess ID Range if not specified
@@ -123,20 +110,16 @@ module BeanstalkdView
123
110
  @jobs = []
124
111
  for i in min..max
125
112
  begin
126
- response = beanstalk.peek_job(i)
127
- if response
128
- ret_value = response.stats
129
- ret_value["body"] = response.body
130
- parsed_body = JSON.parse(response.body)
131
- ret_value["tube"] = parsed_body[0]
132
- @jobs << ret_value
113
+ jobs = beanstalk.jobs.find_all(i)
114
+ jobs.each do |job|
115
+ @jobs << job_to_hash(job)
133
116
  end
134
- rescue Exception => e
135
- #puts "Ignoring NotFoundError: #{ex.class}: #{ex}"
117
+ rescue Beaneater::NotFoundError => e
118
+ # Since we're looping over potentially non-existant jobs, ignore
136
119
  end
137
120
  end
138
121
  erb :peek_range
139
- rescue Beanstalk::NotConnected => @error
122
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
140
123
  erb :error
141
124
  end
142
125
  end
@@ -144,9 +127,8 @@ module BeanstalkdView
144
127
  get "/delete/:tube/:job_id" do
145
128
  begin
146
129
  response = nil
147
- beanstalk.on_tube(params[:tube]) do |conn|
148
- response = conn.delete(params[:job_id].to_i)
149
- end
130
+ job = beanstalk.jobs.find(params[:job_id].to_i)
131
+ response = job.delete if job
150
132
  if response
151
133
  cookies[:beanstalkd_view_notice] = "Deleted Job #{params[:job_id]}"
152
134
  redirect url("/tube/#{params[:tube]}")
@@ -154,14 +136,15 @@ module BeanstalkdView
154
136
  cookies[:beanstalkd_view_notice] = "Error deleting Job #{params[:job_id]}"
155
137
  redirect url("/tube/#{params[:tube]}")
156
138
  end
157
- rescue Beanstalk::NotConnected => @error
139
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
158
140
  erb :error
159
141
  end
160
142
  end
161
143
 
162
144
  post "/pause" do
163
145
  begin
164
- response = beanstalk.pause_tube(params[:tube], params[:delay].to_i)
146
+ tube = beanstalk.tubes[params[:tube]]
147
+ response = tube.pause(params[:delay].to_i)
165
148
  if response
166
149
  cookies[:beanstalkd_view_notice] = "Paused #{params[:tube]}. No jobs will be reserved for #{params[:delay].to_i} seconds."
167
150
  redirect url("/tube/#{params[:tube]}")
@@ -169,10 +152,7 @@ module BeanstalkdView
169
152
  cookies[:beanstalkd_view_notice] = "Error pausing #{params[:tube]}."
170
153
  redirect url("/tube/#{params[:tube]}")
171
154
  end
172
- rescue NameError => @error
173
- cookies[:beanstalkd_view_notice] = "The pause_tube method is currently not implemented by this version of beanstalk-client."
174
- redirect url("/tube/#{params[:tube]}")
175
- rescue Beanstalk::NotConnected => @error
155
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
176
156
  erb :error
177
157
  end
178
158
  end
@@ -180,17 +160,16 @@ module BeanstalkdView
180
160
  post "/kick" do
181
161
  begin
182
162
  response = nil
183
- beanstalk.on_tube(params[:tube]) do |conn|
184
- response = conn.kick(params[:bound].to_i)
185
- end
163
+ tube = beanstalk.tubes[params[:tube]]
164
+ response = tube.kick(params[:bound].to_i)
186
165
  if response
187
- cookies[:beanstalkd_view_notice] = "Kicked #{params[:tube]} for #{response} jobs."
166
+ cookies[:beanstalkd_view_notice] = "Kicked #{params[:tube]}: #{response}"
188
167
  redirect url("/tube/#{params[:tube]}")
189
168
  else
190
169
  cookies[:beanstalkd_view_notice] = "Error kicking #{params[:tube]}."
191
170
  redirect url("/tube/#{params[:tube]}")
192
171
  end
193
- rescue Beanstalk::NotConnected => @error
172
+ rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error
194
173
  erb :error
195
174
  end
196
175
  end
@@ -200,6 +179,8 @@ module BeanstalkdView
200
179
  end
201
180
  alias_method :u, :url_path
202
181
 
182
+ private
183
+
203
184
  def path_prefix
204
185
  request.env['SCRIPT_NAME']
205
186
  end
@@ -209,78 +190,6 @@ module BeanstalkdView
209
190
  cookies[:beanstalkd_view_notice] = ''
210
191
  message
211
192
  end
212
-
213
- private
214
-
215
- # Return the stats data in a format for the Bluff JS UI Charts
216
- def get_chart_data_hash(tube_set)
217
- chart_data = Hash.new
218
- chart_data["total_jobs_data"] = Hash.new
219
- chart_data["buried_jobs_data"] = Hash.new
220
- chart_data["total_jobs_data"]["items"] = Array.new
221
- chart_data["buried_jobs_data"]["items"] = Array.new
222
- tube_set.each do |tube|
223
- begin
224
- stats = beanstalk.stats_tube(tube)
225
- #total_jobs
226
- total_jobs = stats['total-jobs']
227
- if total_jobs > 0
228
- total_datum = Hash.new
229
- total_datum["label"] = tube
230
- total_datum["data"] = total_jobs
231
- chart_data["total_jobs_data"]["items"] << total_datum
232
- end
233
- #buried_jobs
234
- buried_jobs = stats['current-jobs-buried']
235
- if buried_jobs > 0
236
- buried_datum = Hash.new
237
- buried_datum["label"] = tube
238
- buried_datum["data"] = buried_jobs
239
- chart_data["buried_jobs_data"]["items"] << buried_datum
240
- end
241
- rescue Beanstalk::NotFoundError
242
- puts "Ignoring Beanstalk::NotFoundError for #{tube}"
243
- end
244
- end
245
- chart_data
246
- end
247
193
 
248
- # Return a Set of tube names
249
- def tube_set(tubes)
250
- tube_set = Set.new
251
- tubes.keys.each do |key|
252
- tubes[key].each do |tube|
253
- tube_set.add(tube)
254
- end
255
- end
256
- tube_set
257
- end
258
-
259
- # Pick a Minimum Peek Range Based on calls to peek_ready
260
- def guess_min_peek_range(tube_set)
261
- min = 0
262
- tube_set.each do |tube|
263
- response = nil
264
- beanstalk.on_tube(tube) do |conn|
265
- response = conn.peek_ready()
266
- end
267
- if response
268
- if min == 0
269
- min = response.id
270
- else
271
- min = [min, response.id].min
272
- end
273
- end
274
- end
275
- # Add some jitter in the opposite direction of 1/4 range
276
- jitter_min = (min-(GUESS_PEEK_RANGE*0.25)).to_i
277
- [1, jitter_min].max
278
- end
279
-
280
- # Pick a Minimum Peek Range Based on the minimum
281
- def guess_max_peek_range(min)
282
- (min+GUESS_PEEK_RANGE)-1
283
- end
284
-
285
194
  end
286
195
  end
@@ -1,3 +1,3 @@
1
1
  module BeanstalkdView
2
- VERSION = "1.0.2"
2
+ VERSION = "1.1.0"
3
3
  end