adrian 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,14 @@
1
1
  require 'adrian/version'
2
2
 
3
3
  module Adrian
4
- autoload :ArrayQueue, 'adrian/array_queue'
5
- autoload :CompositeQueue, 'adrian/composite_queue'
6
- autoload :DirectoryQueue, 'adrian/directory_queue'
7
- autoload :Dispatcher, 'adrian/dispatcher'
8
- autoload :FileItem, 'adrian/file_item'
9
- autoload :Filters, 'adrian/filters'
10
- autoload :GirlFridayDispatcher, 'adrian/girl_friday_dispatcher'
11
- autoload :QueueItem, 'adrian/queue_item'
12
- autoload :Worker, 'adrian/worker'
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(@available_path)
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(@reserved_path)
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| FileItem.new(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("#{@available_path}/*")
76
+ Dir.glob("#{available_path}/*")
74
77
  end
75
78
 
76
79
  def reserved_files
77
- Dir.glob("#{@reserved_path}/*")
80
+ Dir.glob("#{reserved_path}/*")
78
81
  end
79
82
 
80
83
  def default_reserved_path
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Adrian
2
- VERSION = '1.1.2'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -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
- @q = Adrian::DirectoryQueue.create(:path => Dir.mktmpdir('dir_queue_test'), :delay => 0)
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
@@ -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.1.2
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-19 00:00:00.000000000 Z
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.21
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