carnivore-files 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4150377900b933160fc7b0efb9ad3b022f30d062
4
- data.tar.gz: 29eee65845600e46a3b99d3f15fca7c61d54e679
3
+ metadata.gz: c9393f45222d01b7842f08069591d1e50c3371dc
4
+ data.tar.gz: 515225fcea7f56ae7c1d4596c951ee3ca827668f
5
5
  SHA512:
6
- metadata.gz: 35a949382dbeedde31e19f07c1bc9682876446f7b889defb4352c620d95885ca45330d7f86835aaa106f2b77a3315175a7ff4ef93259b6cf9bd3a1e3dec83217
7
- data.tar.gz: 8bf78650c8048131e5b64ef7c6816fc5704791986dd62a5217a3863e48f6c8e5942a4c9966e4ea7f8e247381513dc28fb483b6b3544e5d0b1aa8db2c783122cc
6
+ metadata.gz: 36b7787ad5dbbcff760a296a5dcb405d1998ed87451ecfd43bdd0461623629a8f368c7076f284409ceed821038af270837e886b5bcd803ccc4766d79013275e0
7
+ data.tar.gz: 435775b1547fa6920900783830c1fd5bbc057606608ed9a7bc7e934a3cf0bfc5790b693ffc41150a14ea0d4cc1573910867835cfc79a0c6eba477616b0814e67
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # v0.2.2
2
+ * Clean up file content fetcher implementations
3
+
1
4
  # v0.2.0
2
5
  * Rename Carnivore::Source::File to Carnivore::Source::CarnFile
3
6
 
@@ -1,6 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + '/lib/'
2
2
  require 'carnivore-files/version'
3
- Gem::Specification.new do |s|
3
+ spec = Gem::Specification.new do |s|
4
4
  s.name = 'carnivore-files'
5
5
  s.version = Carnivore::Files::VERSION.version
6
6
  s.summary = 'Message processing helper'
@@ -11,9 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.license = 'Apache 2.0'
12
12
  s.require_path = 'lib'
13
13
  s.add_dependency 'carnivore', '>= 0.1.8'
14
- # support both but don't want to install both
15
- # update to be setup like carnivore-rabbitmq
16
- # s.add_dependency 'nio4r'
17
14
  s.add_dependency 'sleepy_penguin'
15
+ s.add_dependency 'nio4r'
18
16
  s.files = Dir['{lib}/**/**/*'] + %w(carnivore-files.gemspec README.md CHANGELOG.md)
19
17
  end
@@ -8,7 +8,10 @@ module Carnivore
8
8
  # @return [String] path to file
9
9
  attr_reader :path
10
10
  # @return [Symbol] registry name of fetcher
11
- attr_reader :fetcher_name
11
+ attr_reader :fetcher
12
+
13
+ trap_exit :fetcher_failure
14
+ finalizer :fetcher_destroyer
12
15
 
13
16
  # Setup source
14
17
  #
@@ -16,40 +19,46 @@ module Carnivore
16
19
  # @option args [String] :path path to file
17
20
  # @option args [Symbol] :foundation underlying file interaction library
18
21
  # @option args [Celluloid::Actor] :notify_actor actor to notify on line receive
19
- def setup(args={})
22
+ def setup(*_)
20
23
  @path = ::File.expand_path(args[:path])
21
- @fetcher_name = "log_fetcher_#{name}".to_sym
22
24
  unless(args[:foundation])
23
- args[:foundation] = RUBY_ENGINE == 'jruby' ? :nio4r : :penguin
25
+ args[:foundation] = RUBY_PLATFORM == 'java' ? :nio4r : :penguin
24
26
  end
27
+ end
28
+
29
+ # Start the line fetcher
30
+ def connect
31
+ @fetcher_name = "log_fetcher_#{name}".to_sym
25
32
  case args[:foundation].to_sym
26
33
  when :nio, :nio4r
27
- callback_supervisor.supervise_as(fetcher_name, Carnivore::Files::Util::Fetcher::Nio,
28
- args.merge(:notify_actor => current_actor)
29
- )
34
+ @fetcher = Carnivore::Files::Util::Fetcher::Nio.new(args)
30
35
  else
31
- callback_supervisor.supervise_as(fetcher_name, Carnivore::Files::Util::Fetcher::Penguin,
32
- args.merge(:notify_actor => current_actor)
33
- )
36
+ @fetcher = Carnivore::Files::Util::Fetcher::Penguin.new(args)
34
37
  end
38
+ self.link fetcher
39
+ fetcher.async.start_fetcher
35
40
  end
36
41
 
37
- # @return [Carnivore::Files::Util::Fetcher] line fetcher
38
- def fetcher
39
- callback_supervisor[fetcher_name]
42
+ # Restart file collector if unexpectedly failed
43
+ #
44
+ # @param object [Actor] crashed actor
45
+ # @param reason [Exception, NilClass]
46
+ def fetcher_failure(object, reason)
47
+ if(reason && object == fetcher)
48
+ error "File message collector unexpectedly failed: #{reason} (restarting)"
49
+ connect
50
+ end
40
51
  end
41
52
 
42
- # Start the line fetcher
43
- def connect
44
- fetcher.async.start_fetcher
53
+ def fetcher_destroyer
54
+ if(fetcher && fetcher.alive?)
55
+ fetcher.terminate
56
+ end
45
57
  end
46
58
 
47
59
  # @return [Array<Hash>] return messages
48
60
  def receive(*args)
49
- wait(:new_log_lines)
50
- fetcher.return_lines.map do |l|
51
- format_message(l)
52
- end
61
+ format_message(Celluloid::Future.new{ fetcher.messages.pop }.value)
53
62
  end
54
63
 
55
64
  # Send payload
@@ -1,3 +1,5 @@
1
+ require 'carnivore-files'
2
+
1
3
  module Carnivore
2
4
  module Files
3
5
  # Helper utilities
@@ -15,10 +17,8 @@ module Carnivore
15
17
  attr_reader :path
16
18
  # @return [String] string to split messages on
17
19
  attr_reader :delimiter
18
- # @return [Celluloid::Actor] actor to notify on new messages
19
- attr_reader :notify_actor
20
20
 
21
- # @return [Array] messages
21
+ # @return [Queue] messages
22
22
  attr_accessor :messages
23
23
  # @return [IO] underlying IO instance
24
24
  attr_accessor :io
@@ -33,29 +33,12 @@ module Carnivore
33
33
  @leftover = ''
34
34
  @path = ::File.expand_path(args[:path])
35
35
  @delimiter = args.fetch(:delimiter, "\n")
36
- @notify_actor = args[:notify_actor]
37
- @messages = []
36
+ @messages = Queue.new
38
37
  end
39
38
 
40
39
  # Start the line fetcher
41
40
  def start_fetcher
42
- defer do
43
- loop do
44
- build_socket
45
- messages = nil
46
- selector.select.each do |mon|
47
- self.messages += retrieve_lines
48
- end
49
- notify_actor.signal(:new_logs_lines) unless self.messages.empty?
50
- end
51
- end
52
- end
53
-
54
- # @return [Array<String>] current lines
55
- def return_lines
56
- msgs = messages.dup
57
- messages.clear
58
- msgs
41
+ raise NotImplementedError
59
42
  end
60
43
 
61
44
  # Write line to IO
@@ -84,6 +67,31 @@ module Carnivore
84
67
  end
85
68
  end
86
69
 
70
+ # Build the IO and monitor
71
+ #
72
+ # @return [TrueClass, FalseClass]
73
+ def build_io
74
+ unless(io)
75
+ if(::File.exists?(path))
76
+ @io = ::File.open(path, 'r')
77
+ unless(@waited)
78
+ @io.seek(0, ::IO::SEEK_END) # fast-forward to EOF
79
+ else
80
+ @waited = false
81
+ retrieve_lines.each do |l|
82
+ self.messages << l
83
+ end
84
+ end
85
+ else
86
+ wait_for_file
87
+ build_io
88
+ end
89
+ true
90
+ else
91
+ false
92
+ end
93
+ end
94
+
87
95
  end
88
96
  end
89
97
  end
@@ -26,14 +26,13 @@ module Carnivore
26
26
 
27
27
  # Start the fetcher
28
28
  def start_fetcher
29
- defer do
30
- loop do
31
- build_io
32
- messages = nil
33
- selector.select.each do |mon|
34
- self.messages += retrieve_lines
29
+ loop do
30
+ build_io
31
+ messages = nil
32
+ Celluloid::Future.new{ selector.select }.value.each do |mon|
33
+ retrieve_lines.each do |l|
34
+ self.messages << l
35
35
  end
36
- notify_actor.signal(:new_log_lines) unless self.messages.empty?
37
36
  end
38
37
  end
39
38
  end
@@ -46,6 +45,7 @@ module Carnivore
46
45
  begin
47
46
  unless(io.stat.ino == ::File.stat(path).ino)
48
47
  destroy_io
48
+ @waited = true
49
49
  end
50
50
  rescue Errno::ENOENT
51
51
  destroy_io
@@ -57,19 +57,11 @@ module Carnivore
57
57
  #
58
58
  # @return [TrueClass]
59
59
  def build_io
60
- unless(monitor)
61
- if(::File.exists?(path))
62
- unless(io)
63
- @io = ::File.open(path, 'r')
64
- @io.seek(0, ::IO::SEEK_END) # fast-forward to EOF
65
- end
66
- @monitor = selector.register(io, :r)
67
- else
68
- wait_for_file
69
- build_io
70
- end
60
+ result = super
61
+ if(result && @monitor.nil?)
62
+ @monitor = selector.register(io, :r)
71
63
  end
72
- true
64
+ result
73
65
  end
74
66
 
75
67
  # Destroy the IO instance and monitor
@@ -93,6 +85,7 @@ module Carnivore
93
85
  def wait_for_file
94
86
  warn "Waiting for file to appear (#{path})"
95
87
  until(::File.exists?(path))
88
+ @waited = true
96
89
  sleep(5)
97
90
  end
98
91
  info "File has appeared (#{path})!"
@@ -24,41 +24,41 @@ module Carnivore
24
24
 
25
25
  # Start the fetcher
26
26
  def start_fetcher
27
- defer do
28
- loop do
29
- build_io
30
- notify.each do |event|
31
- event.events.each do |ev|
32
- case ev
33
- when :MODIFY
34
- self.messages += retrieve_lines
35
- when :MOVE_SELF, :DELETE_SELF, :ATTRIB
36
- destroy_io
27
+ loop do
28
+ build_io
29
+ notify.each do |event|
30
+ Celluloid::Future.new{ event.events }.value.each do |ev|
31
+ case ev
32
+ when :MODIFY
33
+ retrieve_lines.each do |l|
34
+ self.messages << l
37
35
  end
36
+ when :MOVE_SELF, :DELETE_SELF, :ATTRIB
37
+ info "Destroying file IO due to FS modification! (#{ev.inspect})"
38
+ destroy_io
39
+ @waited = true
40
+ break
41
+ else
42
+ debug "Received unhandled event: #{ev.inspect}"
38
43
  end
39
- notify_actor.signal(:new_log_lines) unless messages.empty?
40
44
  end
45
+ break unless io
41
46
  end
42
47
  end
43
48
  end
44
49
 
50
+
45
51
  private
46
52
 
47
53
  # Build the IO and monitor
48
54
  #
49
- # @return [TrueClass]
55
+ # @return [TrueClass, FalseClass]
50
56
  def build_io
51
- unless(io)
52
- if(::File.exists?(path))
53
- notify_descriptors[:file_watch] = notify.add_watch(path, :ALL_EVENTS)
54
- @io = ::File.open(path, 'r')
55
- @io.seek(0, ::IO::SEEK_END) # fast-forward to EOF
56
- else
57
- wait_for_file
58
- build_io
59
- end
57
+ result = super
58
+ if(result)
59
+ notify_descriptors[:file_watch] = notify.add_watch(path, :ALL_EVENTS)
60
60
  end
61
- true
61
+ result
62
62
  end
63
63
 
64
64
  # Destroy the IO and monitor
@@ -84,13 +84,12 @@ module Carnivore
84
84
  notify_descriptors[:file_wait] = notify.add_watch(directory, :OPEN)
85
85
  until(notified)
86
86
  warn "Waiting for file to appear (#{path})"
87
- event = notify.take
88
- if(event.name)
89
- notified = ::File.expand_path(event.name) == path
90
- end
87
+ event = Celluloid::Future.new{ notify.take }.value
88
+ notified = ::File.exists?(path)
91
89
  end
92
90
  notify.rm_watch(notify_descriptors.delete(:file_wait))
93
91
  end
92
+ @waited = true
94
93
  info "File has appeared (#{path})!"
95
94
  end
96
95
 
@@ -1,6 +1,6 @@
1
1
  module Carnivore
2
2
  module Files
3
3
  # Current version of library
4
- VERSION = Gem::Version.new('0.2.0')
4
+ VERSION = Gem::Version.new('0.2.2')
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carnivore-files
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-11 00:00:00.000000000 Z
11
+ date: 2015-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: carnivore
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nio4r
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: Carnivore file source
42
56
  email: code@chrisroberts.org
43
57
  executables: []