eventmachine-tail 0.2.20100517011408 → 0.2.20100524185851
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.
- data/lib/em/filetail.rb +29 -7
- data/lib/em/globwatcher.rb +1 -0
- data/samples/tail-with-block.rb +26 -0
- data/test/test_filetail.rb +26 -1
- metadata +4 -3
data/lib/em/filetail.rb
CHANGED
@@ -4,6 +4,7 @@ require "eventmachine"
|
|
4
4
|
require "logger"
|
5
5
|
|
6
6
|
EventMachine.epoll if EventMachine.epoll?
|
7
|
+
EventMachine.kqueue = true if EventMachine.kqueue?
|
7
8
|
|
8
9
|
# Tail a file.
|
9
10
|
#
|
@@ -44,7 +45,7 @@ class EventMachine::FileTail
|
|
44
45
|
# See also: EventMachine::file_tail
|
45
46
|
#
|
46
47
|
public
|
47
|
-
def initialize(path, startpos=-1)
|
48
|
+
def initialize(path, startpos=-1, &block)
|
48
49
|
@path = path
|
49
50
|
@logger = Logger.new(STDOUT)
|
50
51
|
@logger.level = ($DEBUG and Logger::DEBUG or Logger::WARN)
|
@@ -53,6 +54,11 @@ class EventMachine::FileTail
|
|
53
54
|
@file = nil
|
54
55
|
@fstat = File.stat(@path)
|
55
56
|
|
57
|
+
if block_given?
|
58
|
+
@handler = block
|
59
|
+
@buffer = BufferedTokenizer.new
|
60
|
+
end
|
61
|
+
|
56
62
|
if @fstat.directory?
|
57
63
|
raise Errno::EISDIR.new(@path)
|
58
64
|
end
|
@@ -86,9 +92,15 @@ class EventMachine::FileTail
|
|
86
92
|
# end
|
87
93
|
public
|
88
94
|
def receive_data(data)
|
89
|
-
|
90
|
-
|
91
|
-
|
95
|
+
if @handler # FileTail.new called with a block
|
96
|
+
@buffer.extract(data).each do |line|
|
97
|
+
@handler.call(self, line)
|
98
|
+
end
|
99
|
+
else
|
100
|
+
raise NotImplementedError.new("#{self.class.name}#receive_data is not "\
|
101
|
+
"implemented. Did you forget to implement this in your subclass or "\
|
102
|
+
"module?")
|
103
|
+
end
|
92
104
|
end # def receive_data
|
93
105
|
|
94
106
|
# notify is invoked when the file you are tailing has been modified or
|
@@ -217,13 +229,23 @@ module EventMachine
|
|
217
229
|
# path is the path to the file to tail.
|
218
230
|
# handler should be a module implementing 'receive_data' or
|
219
231
|
# must be a subclasses of EventMachine::FileTail
|
220
|
-
|
232
|
+
#
|
233
|
+
# For example:
|
234
|
+
# EM::file_tail("/var/log/messages", MyHandler)
|
235
|
+
#
|
236
|
+
# If a block is given, and the handler is not specified or does
|
237
|
+
# not implement EventMachine::FileTail#receive_data, then it
|
238
|
+
# will be called as such:
|
239
|
+
# EM::file_tail(...) do |filetail, line|
|
240
|
+
# # filetail is the FileTail instance watching the file
|
241
|
+
# # line is the line read from the file
|
242
|
+
# end
|
243
|
+
def self.file_tail(path, handler=nil, *args, &block)
|
221
244
|
# This code mostly styled on what EventMachine does in many of it's other
|
222
245
|
# methods.
|
223
246
|
args = [path, *args]
|
224
247
|
klass = klass_from_handler(EventMachine::FileTail, handler, *args);
|
225
|
-
c = klass.new(*args)
|
226
|
-
yield c if block_given?
|
248
|
+
c = klass.new(*args, &block)
|
227
249
|
return c
|
228
250
|
end # def self.file_tail
|
229
251
|
end # module EventMachine
|
data/lib/em/globwatcher.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Simple 'tail -f' example.
|
4
|
+
# Usage example:
|
5
|
+
# tail.rb /var/log/messages
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "eventmachine"
|
9
|
+
require "eventmachine-tail"
|
10
|
+
|
11
|
+
def main(args)
|
12
|
+
if args.length == 0
|
13
|
+
puts "Usage: #{$0} <path> [path2] [...]"
|
14
|
+
return 1
|
15
|
+
end
|
16
|
+
|
17
|
+
EventMachine.run do
|
18
|
+
args.each do |path|
|
19
|
+
EventMachine::file_tail(path) do |filetail, line|
|
20
|
+
puts line
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end # def main
|
25
|
+
|
26
|
+
exit(main(ARGV))
|
data/test/test_filetail.rb
CHANGED
@@ -11,7 +11,7 @@ require 'testcase_helpers.rb'
|
|
11
11
|
|
12
12
|
# Generate some data
|
13
13
|
DATA = (1..10).collect { |i| rand.to_s }
|
14
|
-
SLEEPMAX =
|
14
|
+
SLEEPMAX = 1
|
15
15
|
|
16
16
|
class Reader < EventMachine::FileTail
|
17
17
|
def initialize(path, startpos=-1, testobj=nil)
|
@@ -67,5 +67,30 @@ class TestFileTail < Test::Unit::TestCase
|
|
67
67
|
EM::file_tail(tmp.path, Reader, 0, self)
|
68
68
|
end # EM.run
|
69
69
|
end # def test_filetail
|
70
|
+
|
71
|
+
def test_filetail_with_block
|
72
|
+
tmp = Tempfile.new("testfiletail")
|
73
|
+
data = DATA.clone
|
74
|
+
EM.run do
|
75
|
+
abort_after_timeout(DATA.length * SLEEPMAX + 10)
|
76
|
+
|
77
|
+
lineno = 0
|
78
|
+
EM::file_tail(tmp.path) do |filetail, line|
|
79
|
+
lineno += 1
|
80
|
+
expected = data.shift
|
81
|
+
assert_equal(expected, line,
|
82
|
+
"Expected '#{expected}' on line #{@lineno}, but got '#{line}'")
|
83
|
+
finish if data.length == 0
|
84
|
+
end
|
85
|
+
|
86
|
+
data_copy = data.clone
|
87
|
+
timer = EM::PeriodicTimer.new(0.2) do
|
88
|
+
tmp.puts data_copy.shift
|
89
|
+
tmp.flush
|
90
|
+
sleep(rand * SLEEPMAX)
|
91
|
+
timer.cancel if data_copy.length == 0
|
92
|
+
end
|
93
|
+
end # EM.run
|
94
|
+
end # def test_filetail_with_block
|
70
95
|
end # class TestFileTail
|
71
96
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 20100524185851
|
9
|
+
version: 0.2.20100524185851
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jordan Sissel
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-24 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- samples/tail.rb
|
45
45
|
- samples/glob-tail.rb
|
46
46
|
- samples/globwatch.rb
|
47
|
+
- samples/tail-with-block.rb
|
47
48
|
- test/test_filetail.rb
|
48
49
|
- test/test_glob.rb
|
49
50
|
- test/alltests.rb
|