conveyor 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|