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 +0 -0
- data/History.txt +4 -0
- data/docs/protocol.mkd +19 -1
- data/lib/conveyor.rb +1 -1
- data/lib/conveyor/channel.rb +37 -5
- data/lib/conveyor/client.rb +20 -0
- data/lib/conveyor/server.rb +31 -9
- data/test/test_channel.rb +58 -0
- data/test/test_priority_queue.rb +1 -1
- data/test/test_server.rb +94 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
data/docs/protocol.mkd
CHANGED
@@ -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
|
+
|
data/lib/conveyor.rb
CHANGED
data/lib/conveyor/channel.rb
CHANGED
@@ -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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
114
|
+
:iterator_groups => @group_iterators.inject({}){|m,(k,v)| m[k] = v; m}
|
83
115
|
}
|
84
116
|
end
|
85
117
|
|
data/lib/conveyor/client.rb
CHANGED
@@ -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
|
data/lib/conveyor/server.rb
CHANGED
@@ -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"]}
|
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.
|
83
|
-
|
84
|
-
|
85
|
-
|
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"]}
|
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"]}
|
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
|
-
|
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
|
-
|
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
|
data/test/test_channel.rb
CHANGED
@@ -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
|
data/test/test_priority_queue.rb
CHANGED
data/test/test_server.rb
CHANGED
@@ -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.
|
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-
|
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
|