Class: Higgs::JournalLogger

Inherits:
Object
  • Object
show all
Includes:
Block
Defined in:
lib/higgs/jlog.rb

Overview

journal log writer

Constant Summary collapse

CVS_ID =

for ident(1)

'$Id: jlog.rb 841 2008-12-24 09:23:20Z toki $'
MAGIC_SYMBOL =
'HIGGS_JLOG'
EOF_MARK =
:END_OF_JLOG
BIN_EOF_MARK =
Marshal.dump(EOF_MARK)

Constants included from Block

Block::BLOCK_SIZE, Block::BODY_HASH, Block::BODY_HASH_BIN, Block::FMT_VERSION, Block::HEAD_CKSUM_BITS, Block::HEAD_CKSUM_FMT, Block::HEAD_CKSUM_POS, Block::HEAD_FMT

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Block

block_read, block_write, head_read, head_write, padding_size

Constructor Details

#initialize(out, sync = false, hash_type = :MD5) ⇒ JournalLogger

see Higgs::Block#block_write for hash_type



26
27
28
29
30
# File 'lib/higgs/jlog.rb', line 26

def initialize(out, sync=false, hash_type=:MD5)
  @out = out
  @sync = sync
  @hash_type = hash_type
end

Class Method Details

.each_log(path) ⇒ Object



139
140
141
142
143
144
145
146
147
# File 'lib/higgs/jlog.rb', line 139

def each_log(path)
  File.open(path, 'r') {|f|
    f.binmode
    scan_log(f) do |log|
      yield(log)
    end
  }
  nil
end

.eof_mark(out) ⇒ Object



116
117
118
119
# File 'lib/higgs/jlog.rb', line 116

def eof_mark(out)
  Block.block_write(out, MAGIC_SYMBOL, BIN_EOF_MARK)
  nil
end

.has_eof_mark?(path) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/higgs/jlog.rb', line 73

def has_eof_mark?(path)
  File.open(path, 'r') {|f|
    f.binmode
    fsiz = f.stat.size
    if (fsiz < Block::BLOCK_SIZE * 2) then
      return false
    end
    f.seek(fsiz - Block::BLOCK_SIZE * 2)

    begin
      bin_log = Block.block_read(f, MAGIC_SYMBOL) or return
      log = Marshal.load(bin_log)
      if (log == EOF_MARK) then
        return true
      end
    rescue Block::BrokenError
      return false
    end
  }

  false
end

.need_for_recovery?(path) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/higgs/jlog.rb', line 96

def need_for_recovery?(path)
  (File.exist? path) && ! (has_eof_mark? path)
end

.open(path, *args) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/higgs/jlog.rb', line 100

def open(path, *args)
  begin
    f = File.open(path, File::WRONLY | File::CREAT | File::EXCL, 0660)
  rescue Errno::EEXIST
    if (need_for_recovery? path) then
      raise "need for recovery: #{path}"
    end
    f = File.open(path, File::WRONLY, 0660)
    fsiz = f.stat.size
    f.truncate(fsiz - Block::BLOCK_SIZE * 2)
  end
  f.binmode
  f.seek(0, IO::SEEK_END)
  new(f, *args)
end

.scan_log(io) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/higgs/jlog.rb', line 121

def scan_log(io)
  safe_pos = io.tell
  begin
    while (bin_log = Block.block_read(io, MAGIC_SYMBOL))
      log = Marshal.load(bin_log)
      if (log == EOF_MARK) then
        break
      end
      yield(log)
      safe_pos = io.tell
    end
  rescue Block::BrokenError
    io.seek(safe_pos)
    raise
  end
  self
end

Instance Method Details

#close(eof = true) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/higgs/jlog.rb', line 64

def close(eof=true)
  write_EOF if eof
  @out.fsync
  @out.close
  @out = nil
  nil
end

#sizeObject



36
37
38
# File 'lib/higgs/jlog.rb', line 36

def size
  @out.stat.size
end

#sync?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/higgs/jlog.rb', line 32

def sync?
  @sync
end

#write(log, hash_type = nil) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/higgs/jlog.rb', line 40

def write(log, hash_type=nil)
  bin_log = Marshal.dump(log)
  start_pos = @out.tell
  commit_completed = false
  begin
    block_write(@out, MAGIC_SYMBOL, bin_log, hash_type || @hash_type)
    if (@sync) then
      @out.fsync
    else
      @out.flush
    end
    commit_completed = true
  ensure
    @out.truncate(start_pos) unless commit_completed
  end

  self
end

#write_EOFObject



59
60
61
62
# File 'lib/higgs/jlog.rb', line 59

def write_EOF
  JournalLogger.eof_mark(@out)
  self
end