adrian 1.1.2 → 1.2.0

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.
@@ -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