Class: Brute::Contrib::LogFile
- Inherits:
-
File
- Object
- File
- Brute::Contrib::LogFile
- Includes:
- File::Tail
- Defined in:
- lib/brute/contrib/log_file.rb
Overview
A line-oriented, append-only log file that doubles as a work queue.
Every entry is exactly one line — newlines in the input are folded to
spaces on the way in — so a line is the unit of both storage and
retrieval. Reads are destructive: pop takes the newest line off the
end, drain yields every line oldest-first and empties the file.
log = Brute::Contrib::LogFile.new("tmp/queue.log")
log.append("something happened")
log.pop # => "something happened"
log.drain { |line| handle(line) }
Safe across both threads (a mutex) and processes (an exclusive flock), so several agents can share one file without losing lines.
Instance Method Summary collapse
-
#append(line) ⇒ Object
Append one line.
-
#drain ⇒ Object
Yield every line oldest-first, then empty the file.
-
#initialize(path) ⇒ LogFile
constructor
A new instance of LogFile.
-
#pop ⇒ Object
Remove and return the newest line, or nil when the file is empty.
Constructor Details
#initialize(path) ⇒ LogFile
Returns a new instance of LogFile.
25 26 27 28 29 |
# File 'lib/brute/contrib/log_file.rb', line 25 def initialize(path) FileUtils.mkdir_p(File.dirname(path)) super(path, File::RDWR | File::CREAT | File::APPEND) @mutex = Mutex.new end |
Instance Method Details
#append(line) ⇒ Object
Append one line. Blank (or whitespace-only) input is a no-op and returns nil; otherwise returns the stripped line that was written.
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/brute/contrib/log_file.rb', line 33 def append(line) strip_whitespace(line).then do |stripped_text| unless stripped_text.empty? locked do puts(stripped_text) flush stripped_text end end end end |
#drain ⇒ Object
Yield every line oldest-first, then empty the file. Requires a block — without one there is nowhere for the lines to go, so it raises rather than discarding them.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/brute/contrib/log_file.rb', line 57 def drain locked do if block_given? backward(line_count) each_line { |x| yield x.chomp } truncate(0) else raise "No block given..." end end end |
#pop ⇒ Object
Remove and return the newest line, or nil when the file is empty.
46 47 48 49 50 51 52 |
# File 'lib/brute/contrib/log_file.rb', line 46 def pop locked do backward(1) offset = tell gets&.chomp.tap { truncate(offset) } end end |