adrian 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/adrian.rb +10 -9
- data/lib/adrian/directory_queue.rb +10 -7
- data/lib/adrian/file_item.rb +2 -0
- data/lib/adrian/rotating_directory_queue.rb +25 -0
- data/lib/adrian/version.rb +1 -1
- data/test/directory_queue_test.rb +9 -1
- data/test/file_item_test.rb +11 -0
- data/test/rotating_directory_queue_test.rb +57 -0
- metadata +12 -3
data/lib/adrian.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'adrian/version'
|
2
2
|
|
3
3
|
module Adrian
|
4
|
-
autoload :ArrayQueue,
|
5
|
-
autoload :CompositeQueue,
|
6
|
-
autoload :DirectoryQueue,
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
4
|
+
autoload :ArrayQueue, 'adrian/array_queue'
|
5
|
+
autoload :CompositeQueue, 'adrian/composite_queue'
|
6
|
+
autoload :DirectoryQueue, 'adrian/directory_queue'
|
7
|
+
autoload :RotatingDirectoryQueue, 'adrian/rotating_directory_queue'
|
8
|
+
autoload :Dispatcher, 'adrian/dispatcher'
|
9
|
+
autoload :FileItem, 'adrian/file_item'
|
10
|
+
autoload :Filters, 'adrian/filters'
|
11
|
+
autoload :GirlFridayDispatcher, 'adrian/girl_friday_dispatcher'
|
12
|
+
autoload :QueueItem, 'adrian/queue_item'
|
13
|
+
autoload :Worker, 'adrian/worker'
|
13
14
|
end
|
@@ -11,7 +11,7 @@ module Adrian
|
|
11
11
|
queue
|
12
12
|
end
|
13
13
|
|
14
|
-
attr_reader :available_path, :reserved_path
|
14
|
+
attr_reader :available_path, :reserved_path, :logger
|
15
15
|
|
16
16
|
# Note:
|
17
17
|
# There is the possibility of an item being consumed by multiple processes when its still in the queue after its lock expires.
|
@@ -21,6 +21,7 @@ module Adrian
|
|
21
21
|
def initialize(options = {})
|
22
22
|
@available_path = options.fetch(:path)
|
23
23
|
@reserved_path = options.fetch(:reserved_path, default_reserved_path)
|
24
|
+
@logger = options[:logger]
|
24
25
|
filters << Filters::FileLock.new(:duration => options[:lock_duration], :reserved_path => reserved_path)
|
25
26
|
filters << Filters::Delay.new(:duration => options[:delay]) if options[:delay]
|
26
27
|
end
|
@@ -35,7 +36,7 @@ module Adrian
|
|
35
36
|
|
36
37
|
def push(value)
|
37
38
|
item = wrap_item(value)
|
38
|
-
item.move(
|
39
|
+
item.move(available_path)
|
39
40
|
item.touch
|
40
41
|
self
|
41
42
|
end
|
@@ -48,11 +49,13 @@ module Adrian
|
|
48
49
|
protected
|
49
50
|
|
50
51
|
def wrap_item(value)
|
51
|
-
value.is_a?(FileItem) ? value : FileItem.new(value)
|
52
|
+
item = value.is_a?(FileItem) ? value : FileItem.new(value)
|
53
|
+
item.logger ||= logger
|
54
|
+
item
|
52
55
|
end
|
53
56
|
|
54
57
|
def reserve(item)
|
55
|
-
item.move(
|
58
|
+
item.move(reserved_path)
|
56
59
|
item.touch
|
57
60
|
true
|
58
61
|
rescue Errno::ENOENT => e
|
@@ -60,7 +63,7 @@ module Adrian
|
|
60
63
|
end
|
61
64
|
|
62
65
|
def items
|
63
|
-
items = files.map { |file|
|
66
|
+
items = files.map { |file| wrap_item(file) }
|
64
67
|
items.reject! { |item| !item.exist? || filter?(item) }
|
65
68
|
items.sort_by(&:updated_at)
|
66
69
|
end
|
@@ -70,11 +73,11 @@ module Adrian
|
|
70
73
|
end
|
71
74
|
|
72
75
|
def available_files
|
73
|
-
Dir.glob("#{
|
76
|
+
Dir.glob("#{available_path}/*")
|
74
77
|
end
|
75
78
|
|
76
79
|
def reserved_files
|
77
|
-
Dir.glob("#{
|
80
|
+
Dir.glob("#{reserved_path}/*")
|
78
81
|
end
|
79
82
|
|
80
83
|
def default_reserved_path
|
data/lib/adrian/file_item.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Adrian
|
2
2
|
class FileItem < QueueItem
|
3
|
+
attr_accessor :logger
|
3
4
|
|
4
5
|
def initialize(value, created_at = Time.now)
|
5
6
|
@value = value
|
@@ -22,6 +23,7 @@ module Adrian
|
|
22
23
|
|
23
24
|
def move(destination)
|
24
25
|
destination_path = File.join(destination, File.basename(path))
|
26
|
+
logger.info("Moving #{path} to #{destination_path}") if logger
|
25
27
|
File.rename(path, destination_path)
|
26
28
|
@value = destination_path
|
27
29
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'adrian/directory_queue'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Adrian
|
5
|
+
|
6
|
+
class RotatingDirectoryQueue < DirectoryQueue
|
7
|
+
attr_reader :time_format
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
super
|
11
|
+
@time_format = options.fetch(:time_format, '%Y-%m-%d')
|
12
|
+
end
|
13
|
+
|
14
|
+
def available_path
|
15
|
+
path = "#{super}/#{Time.now.strftime(time_format)}"
|
16
|
+
|
17
|
+
if path != @previous_avaliable_path
|
18
|
+
FileUtils.mkdir_p(path)
|
19
|
+
@previous_avaliable_path = path
|
20
|
+
end
|
21
|
+
|
22
|
+
path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/adrian/version.rb
CHANGED
@@ -2,10 +2,12 @@ require_relative 'test_helper'
|
|
2
2
|
require 'tempfile'
|
3
3
|
require 'tmpdir'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'logger'
|
5
6
|
|
6
7
|
describe Adrian::DirectoryQueue do
|
7
8
|
before do
|
8
|
-
@
|
9
|
+
@logger = Logger.new('/dev/null')
|
10
|
+
@q = Adrian::DirectoryQueue.create(:path => Dir.mktmpdir('dir_queue_test'), :delay => 0, :logger => @logger)
|
9
11
|
end
|
10
12
|
|
11
13
|
after do
|
@@ -87,6 +89,12 @@ describe Adrian::DirectoryQueue do
|
|
87
89
|
assert_equal nil, @q.pop
|
88
90
|
end
|
89
91
|
|
92
|
+
it "set's the logger on the item" do
|
93
|
+
@item.logger.must_be_nil
|
94
|
+
@q.push(@item)
|
95
|
+
@q.pop.logger.must_equal @logger
|
96
|
+
end
|
97
|
+
|
90
98
|
end
|
91
99
|
|
92
100
|
describe 'push' do
|
data/test/file_item_test.rb
CHANGED
@@ -59,6 +59,17 @@ describe Adrian::FileItem do
|
|
59
59
|
assert_equal @destination, File.dirname(@item.path)
|
60
60
|
end
|
61
61
|
|
62
|
+
it 'logs the move on the logger' do
|
63
|
+
destination_file_name = File.join(@destination, File.basename(@item.path))
|
64
|
+
logger = MiniTest::Mock.new
|
65
|
+
logger.expect(:info, nil, ["Moving #{@item.path} to #{destination_file_name}"])
|
66
|
+
@item.logger = logger
|
67
|
+
|
68
|
+
@item.move(@destination)
|
69
|
+
|
70
|
+
logger.verify
|
71
|
+
end
|
72
|
+
|
62
73
|
end
|
63
74
|
|
64
75
|
describe 'touch' do
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
describe Adrian::RotatingDirectoryQueue do
|
7
|
+
before do
|
8
|
+
@root_path = Dir.mktmpdir('dir_queue_test')
|
9
|
+
@q = Adrian::RotatingDirectoryQueue.create(:path => @root_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
FileUtils.rm_r(@root_path, :force => true)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'pop' do
|
17
|
+
it 'only provides files available in the current time-stamped directory' do
|
18
|
+
@item1 = Adrian::FileItem.new(Tempfile.new('item1').path)
|
19
|
+
@item2 = Adrian::FileItem.new(Tempfile.new('item2').path)
|
20
|
+
@item3 = Adrian::FileItem.new(Tempfile.new('item3').path)
|
21
|
+
|
22
|
+
Time.stub(:now, Time.now) do
|
23
|
+
todays_directory = File.join(@root_path, Time.now.strftime('%Y-%m-%d'))
|
24
|
+
tomorrows_directory = File.join(@root_path, (Time.now + 60 * 60 * 24).strftime('%Y-%m-%d'))
|
25
|
+
|
26
|
+
FileUtils.mkdir_p(todays_directory)
|
27
|
+
FileUtils.mkdir_p(tomorrows_directory)
|
28
|
+
|
29
|
+
@item1.move(todays_directory)
|
30
|
+
@item2.move(tomorrows_directory)
|
31
|
+
@item3.move(@root_path)
|
32
|
+
|
33
|
+
@q.pop.must_equal @item1
|
34
|
+
@q.pop.must_be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'push' do
|
40
|
+
before do
|
41
|
+
@item = Adrian::FileItem.new(Tempfile.new('item').path)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'moves the file to the time-stamped available directory' do
|
45
|
+
Time.stub(:now, Time.now) do
|
46
|
+
original_path = @item.path
|
47
|
+
@q.push(@item)
|
48
|
+
|
49
|
+
assert_equal false, File.exist?(original_path)
|
50
|
+
assert_equal true, File.exist?(File.join(@q.available_path, @item.name))
|
51
|
+
|
52
|
+
@item.path.must_equal File.join(@root_path, Time.now.strftime('%Y-%m-%d'), @item.name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adrian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-10-
|
13
|
+
date: 2012-10-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/adrian/girl_friday_dispatcher.rb
|
93
93
|
- lib/adrian/queue.rb
|
94
94
|
- lib/adrian/queue_item.rb
|
95
|
+
- lib/adrian/rotating_directory_queue.rb
|
95
96
|
- lib/adrian/version.rb
|
96
97
|
- lib/adrian/worker.rb
|
97
98
|
- lib/adrian.rb
|
@@ -104,6 +105,7 @@ files:
|
|
104
105
|
- test/file_item_test.rb
|
105
106
|
- test/filters_test.rb
|
106
107
|
- test/girl_friday_dispatcher_test.rb
|
108
|
+
- test/rotating_directory_queue_test.rb
|
107
109
|
- test/test_helper.rb
|
108
110
|
- test/worker_test.rb
|
109
111
|
- README.md
|
@@ -120,15 +122,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
122
|
- - ! '>='
|
121
123
|
- !ruby/object:Gem::Version
|
122
124
|
version: '0'
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
hash: -4323319423024807981
|
123
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
129
|
none: false
|
125
130
|
requirements:
|
126
131
|
- - ! '>='
|
127
132
|
- !ruby/object:Gem::Version
|
128
133
|
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: -4323319423024807981
|
129
137
|
requirements: []
|
130
138
|
rubyforge_project:
|
131
|
-
rubygems_version: 1.8.
|
139
|
+
rubygems_version: 1.8.24
|
132
140
|
signing_key:
|
133
141
|
specification_version: 3
|
134
142
|
summary: Adrian does not do any real work, but is really good at delegating it
|
@@ -142,5 +150,6 @@ test_files:
|
|
142
150
|
- test/file_item_test.rb
|
143
151
|
- test/filters_test.rb
|
144
152
|
- test/girl_friday_dispatcher_test.rb
|
153
|
+
- test/rotating_directory_queue_test.rb
|
145
154
|
- test/test_helper.rb
|
146
155
|
- test/worker_test.rb
|