conveyor 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,7 @@
1
+ == 0.1.4 / 2008-02-19
2
+ * support for getting multiple items at once
3
+ * rewinding implemented for group iterators
4
+
1
5
  == 0.1.2 / 2008-02-05
2
6
  * various bugfixes
3
7
 
@@ -68,4 +68,22 @@ Request
68
68
  : POST /channels/{channel name}?rewind_id={id}
69
69
 
70
70
  Response
71
- :success: 200
71
+ :success: 200
72
+
73
+ ### Get next n ###
74
+
75
+ Request
76
+ : GET /channels/{channel name}?next&n={n}
77
+
78
+ Response
79
+ : JSON array of objects, which have the keys 'id', 'hash' and 'data'
80
+
81
+
82
+ ### Get next n for group ###
83
+
84
+ Request
85
+ : GET /channels/{channel name}?next&n={n}&group={group}
86
+
87
+ Response
88
+ : JSON array of objects, which have the keys 'id', 'hash' and 'data'
89
+
@@ -1,4 +1,4 @@
1
1
  module Conveyor
2
- VERSION = '0.1.3'
2
+ VERSION = '0.1.4'
3
3
  QUALITY = 'alpha'
4
4
  end
@@ -62,10 +62,42 @@ module Conveyor
62
62
  r = nil
63
63
  Thread.exclusive do
64
64
  @group_iterators[group] = 1 unless @group_iterators.key?(group)
65
- r = get(@group_iterators[group])
66
- @group_iterators[group] += 1
67
- group_iterators_file(group) do |f|
68
- f.write("#{@group_iterators[group]}\n")
65
+ if @iterator <= @last_id
66
+ r = get(@group_iterators[group])
67
+ @group_iterators[group] += 1
68
+ group_iterators_file(group) do |f|
69
+ f.write("#{@group_iterators[group]}\n")
70
+ end
71
+ else
72
+ nil
73
+ end
74
+ end
75
+ r
76
+ end
77
+
78
+ def get_next_n n
79
+ r = []
80
+ Thread.exclusive do
81
+ while r.length < n && @iterator <= @last_id
82
+ r << get(@iterator)
83
+ @iterator += 1
84
+ @iterator_file.write("#{@iterator}\n")
85
+ r
86
+ end
87
+ end
88
+ r
89
+ end
90
+
91
+ def get_next_n_by_group n, group
92
+ r = []
93
+ Thread.exclusive do
94
+ @group_iterators[group] = 1 unless @group_iterators.key?(group)
95
+ while r.length < n && @group_iterators[group] < @last_id
96
+ r << get(@group_iterators[group])
97
+ @group_iterators[group] += 1
98
+ group_iterators_file(group) do |f|
99
+ f.write("#{@group_iterators[group]}\n")
100
+ end
69
101
  end
70
102
  end
71
103
  r
@@ -79,7 +111,7 @@ module Conveyor
79
111
  },
80
112
  :data_files => @data_files.collect{|f| {:path => f.path, :bytes => File.size(f.path)}},
81
113
  :iterator => {:position => @iterator},
82
- :iterator_groups => @group_iterators.inject({}){|k,v, m| m[k] = v; m}
114
+ :iterator_groups => @group_iterators.inject({}){|m,(k,v)| m[k] = v; m}
83
115
  }
84
116
  end
85
117
 
@@ -31,5 +31,25 @@ module Conveyor
31
31
  @conn.get("/channels/#{channel_name}?next").body
32
32
  end
33
33
  end
34
+
35
+ def channel_status channel_name
36
+ JSON::parse(@conn.get("/channels/#{channel_name}").body)
37
+ end
38
+
39
+ def get_next_n channel_name, n = 10, group = nil
40
+ if group
41
+ JSON.parse(@conn.get("/channels/#{channel_name}?next&n=#{n}&group=#{group}").body)
42
+ else
43
+ JSON.parse(@conn.get("/channels/#{channel_name}?next&n=#{n}").body)
44
+ end
45
+ end
46
+
47
+ def rewind channel_name, id, group=nil
48
+ if group
49
+ @conn.post("/channels/#{channel_name}?rewind_id=#{id}&group=#{group}", nil)
50
+ else
51
+ @conn.post("/channels/#{channel_name}?rewind_id=#{id}", nil)
52
+ end
53
+ end
34
54
  end
35
55
  end
@@ -68,7 +68,7 @@ module Conveyor
68
68
  response.start(202) do |head, out|
69
69
  out.write("channel already exists. didn't do anything")
70
70
  end
71
- i "#{request.params["REMOTE_ADDR"]} PUT #{request.params["REQUEST_PATH"]} 202"
71
+ i "#{request.params["REMOTE_ADDR"]} PUT #{request.params["REQUEST_PATH"]} "
72
72
  end
73
73
  else
74
74
  response.start(406) do |head, out|
@@ -79,10 +79,17 @@ module Conveyor
79
79
  elsif request.post? && m = request.path_match(%r{/channels/(.*)})
80
80
  if @channels.key?(m.captures[0])
81
81
  params = Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING'])
82
- if params.include?('rewind_id')
83
- @channels[m.captures[0]].rewind(:id => params['rewind_id']).to_i # TODO make sure this is an integer
84
- response.start(200) do |head, out|
85
- out.write "iterator rewound to #{params['rewind_id']}"
82
+ if params.key?('rewind_id')
83
+ if params['group']
84
+ @channels[m.captures[0]].rewind(:id => params['rewind_id'], :group => params['group']).to_i # TODO make sure this is an integer
85
+ response.start(200) do |head, out|
86
+ out.write "iterator rewound to #{params['rewind_id']}"
87
+ end
88
+ else
89
+ @channels[m.captures[0]].rewind(:id => params['rewind_id']).to_i # TODO make sure this is an integer
90
+ response.start(200) do |head, out|
91
+ out.write "iterator rewound to #{params['rewind_id']}"
92
+ end
86
93
  end
87
94
  else
88
95
  if request.params.include?('HTTP_DATE') && d = Time.parse(request.params['HTTP_DATE'])
@@ -90,12 +97,12 @@ module Conveyor
90
97
  response.start(202) do |head, out|
91
98
  head["Location"] = "/channels/#{m.captures[0]}/#{id}"
92
99
  end
93
- i "#{request.params["REMOTE_ADDR"]} GET #{request.params["REQUEST_PATH"]} 202"
100
+ i "#{request.params["REMOTE_ADDR"]} POST #{request.params["REQUEST_PATH"]} 202"
94
101
  else
95
102
  response.start(400) do |head, out|
96
103
  out.write "A valid Date header is required for all POSTs."
97
104
  end
98
- i "#{request.params["REMOTE_ADDR"]} GET #{request.params["REQUEST_PATH"]} 400"
105
+ i "#{request.params["REMOTE_ADDR"]} POST #{request.params["REQUEST_PATH"]} 400"
99
106
  end
100
107
  end
101
108
  end
@@ -111,9 +118,20 @@ module Conveyor
111
118
  params = Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING'])
112
119
  if params.key? 'next'
113
120
  if params.key? 'group'
114
- headers, content = @channels[m.captures[0]].get_next_by_group(params['group'])
121
+ if params.key? 'n'
122
+ list = @channels[m.captures[0]].get_next_n_by_group(params['n'].to_i, params['group'])
123
+ else
124
+ headers, content = @channels[m.captures[0]].get_next_by_group(params['group'])
125
+ end
115
126
  else
116
- headers, content = @channels[m.captures[0]].get_next
127
+ if params.key? 'n'
128
+ list = @channels[m.captures[0]].get_next_n(params['n'].to_i)
129
+ list = list.map do |i|
130
+ {:data => i[1], :hash => i[0][:hash], :id => i[0][:id]}
131
+ end
132
+ else
133
+ headers, content = @channels[m.captures[0]].get_next
134
+ end
117
135
  end
118
136
  else
119
137
  response.start(200) do |head, out|
@@ -136,6 +154,10 @@ module Conveyor
136
154
  out.write content
137
155
  end
138
156
  i "#{request.params["REMOTE_ADDR"]} GET #{request.params["REQUEST_PATH"]} 200 #{headers[:id]} #{headers[:length]} #{headers[:hash]}"
157
+ elsif list
158
+ response.start(200) do |head, out|
159
+ out.write list.to_json
160
+ end
139
161
  end
140
162
 
141
163
  end
@@ -180,4 +180,62 @@ class TestConveyorChannel < Test::Unit::TestCase
180
180
  assert BaseChannel.valid_channel_name?('-')
181
181
  assert BaseChannel.valid_channel_name?('_')
182
182
  end
183
+
184
+ def test_get_next_n
185
+ FileUtils.rm_r '/tmp/asdfasdf' rescue nil
186
+ c = Conveyor::Channel.new '/tmp/asdfasdf'
187
+ 100.times {|i| c.post i.to_s}
188
+
189
+ 12.times do |j|
190
+ r = c.get_next_n 10
191
+ r.each_with_index do |f, i|
192
+ assert_equal Digest::MD5.hexdigest((j*10 + i).to_s), f[0][:hash]
193
+ assert_equal((j*10 + i).to_s.length, f[0][:length])
194
+ assert_equal((j*10 + i)+1, f[0][:id])
195
+ assert_equal((j*10 + i).to_s, f[1])
196
+ end
197
+ end
198
+
199
+ 100.times {|i| c.post i.to_s}
200
+
201
+ 12.times do |j|
202
+ r = c.get_next_n 10
203
+ r.each_with_index do |f, i|
204
+ assert_equal Digest::MD5.hexdigest((j*10 + i).to_s), f[0][:hash]
205
+ assert_equal((j*10 + i).to_s.length, f[0][:length])
206
+ assert_equal((100 + j*10 + i)+1, f[0][:id])
207
+ assert_equal((j*10 + i).to_s, f[1])
208
+ end
209
+ end
210
+ end
211
+
212
+ def test_get_next_n_by_group
213
+ FileUtils.rm_r '/tmp/asdfasdf'
214
+ c = Conveyor::Channel.new '/tmp/asdfasdf'
215
+ 100.times {|i| c.post i.to_s}
216
+
217
+ 10.times do |j|
218
+ r = c.get_next_n_by_group 10, 'foo'
219
+ r.each_with_index do |f, i|
220
+ assert_equal Digest::MD5.hexdigest((j*10 + i).to_s), f[0][:hash]
221
+ assert_equal((j*10 + i).to_s.length, f[0][:length])
222
+ assert_equal((j*10 + i)+1, f[0][:id])
223
+ assert_equal((j*10 + i).to_s, f[1])
224
+ end
225
+ end
226
+
227
+ assert_equal [], c.get_next_n_by_group(10, 'foo')
228
+
229
+ 10.times do |j|
230
+ r = c.get_next_n_by_group 10, 'bar'
231
+ r.each_with_index do |f, i|
232
+ assert_equal Digest::MD5.hexdigest((j*10 + i).to_s), f[0][:hash]
233
+ assert_equal((j*10 + i).to_s.length, f[0][:length])
234
+ assert_equal((j*10 + i)+1, f[0][:id])
235
+ assert_equal((j*10 + i).to_s, f[1])
236
+ end
237
+ end
238
+ assert_equal [], c.get_next_n_by_group(10, 'bar')
239
+ end
240
+
183
241
  end
@@ -9,7 +9,7 @@ class TestPriorityQueue < Test::Unit::TestCase
9
9
 
10
10
  pq << 1 << 2 << -1
11
11
 
12
- assert_equal -1, pq.pop
12
+ assert_equal(-1, pq.pop)
13
13
  assert_equal 1, pq.pop
14
14
  assert_equal 2, pq.pop
15
15
  end
@@ -1,8 +1,10 @@
1
1
  require "test/unit"
2
2
  require "conveyor/server"
3
3
  require 'net/http'
4
+ require 'conveyor/client'
4
5
 
5
6
  class TestConveyorServer < Test::Unit::TestCase
7
+ include Conveyor
6
8
  def setup
7
9
  FileUtils.rm_r('/tmp/asdf') rescue nil
8
10
  FileUtils.mkdir('/tmp/asdf')
@@ -152,4 +154,96 @@ class TestConveyorServer < Test::Unit::TestCase
152
154
  assert_kind_of Net::HTTPNotFound, req
153
155
  end
154
156
  end
157
+
158
+ def test_group_rewind
159
+ chan = 'test_group_rewind'
160
+ c = Client.new 'localhost'
161
+ c.create_channel chan
162
+ c.post chan, 'foo'
163
+
164
+ assert_equal 'foo', c.get_next(chan, 'bar')
165
+ c.rewind(chan, 1, 'bar')
166
+ assert_equal 'foo', c.get_next(chan, 'bar')
167
+ c.rewind(chan, 1, 'bar')
168
+ end
169
+
170
+
171
+ def test_get_next_by_group
172
+ c = Conveyor::Client.new 'localhost'
173
+ chan = 'asdf'
174
+ c.create_channel chan
175
+ c.post chan, 'foo'
176
+ c.post chan, 'bar'
177
+ c.post chan, 'bam'
178
+
179
+ group = 'bam'
180
+
181
+ assert_equal 'foo', c.get_next(chan, group)
182
+ assert_equal 'bar', c.get_next(chan, group)
183
+ assert_equal 'bam', c.get_next(chan, group)
184
+ assert_equal '', c.get_next(chan, group)
185
+
186
+ group = 'bar'
187
+ assert_equal 'foo', c.get_next(chan, group)
188
+ assert_equal 'bar', c.get_next(chan, group)
189
+ assert_equal 'bam', c.get_next(chan, group)
190
+ assert_equal '', c.get_next(chan, group)
191
+ end
192
+
193
+ def test_get_next_n
194
+ chan = 'test_get_next_n'
195
+ c = Client.new 'localhost'
196
+ c.create_channel chan
197
+ 100.times {|i| c.post chan, i.to_s}
198
+
199
+ 10.times do |j|
200
+ r = c.get_next_n chan, 10
201
+ r.each_with_index do |f, i|
202
+ assert_equal((j*10 + i)+1, f["id"])
203
+ assert_equal(Digest::MD5.hexdigest((j*10 + i).to_s), f["hash"])
204
+ assert_equal((j*10 + i).to_s, f["data"])
205
+ end
206
+ end
207
+
208
+ 100.times {|i| c.post chan, i.to_s}
209
+
210
+ 10.times do |j|
211
+ r = c.get_next_n chan, 10
212
+ r.each_with_index do |f, i|
213
+ assert_equal(Digest::MD5.hexdigest((j*10 + i).to_s), f["hash"])
214
+ assert_equal((100 + j*10 + i)+1, f["id"])
215
+ assert_equal((j*10 + i).to_s, f["data"])
216
+ end
217
+ end
218
+ end
219
+
220
+ def test_get_next_n_by_group
221
+ chan = 'test_get_next_n_by_group'
222
+ c = Client.new 'localhost'
223
+ c.create_channel chan
224
+ 100.times {|i| c.post chan, i.to_s}
225
+
226
+ 10.times do |j|
227
+ r = c.get_next_n chan, 10, 'foo'
228
+ r.each_with_index do |f, i|
229
+ assert_equal(Digest::MD5.hexdigest((j*10 + i).to_s), f[0]["hash"])
230
+ assert_equal((j*10 + i).to_s.length, f[0]["length"])
231
+ assert_equal((j*10 + i)+1, f[0]["id"])
232
+ assert_equal((j*10 + i).to_s, f[1])
233
+ end
234
+ end
235
+
236
+ assert_equal [], c.get_next_n(chan, 10, 'foo')
237
+
238
+ 10.times do |j|
239
+ r = c.get_next_n chan, 10, 'bar'
240
+ r.each_with_index do |f, i|
241
+ assert_equal Digest::MD5.hexdigest((j*10 + i).to_s), f[0]["hash"]
242
+ assert_equal((j*10 + i).to_s.length, f[0]["length"])
243
+ assert_equal((j*10 + i)+1, f[0]["id"])
244
+ assert_equal((j*10 + i).to_s, f[1])
245
+ end
246
+ end
247
+ assert_equal [], c.get_next_n(chan, 10, 'bar')
248
+ end
155
249
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conveyor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan King
@@ -30,7 +30,7 @@ cert_chain:
30
30
  Zls3y84CmyAEGg==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2008-02-15 00:00:00 -08:00
33
+ date: 2008-02-19 00:00:00 -08:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
metadata.gz.sig CHANGED
Binary file