Class: Yobi::ResticOutput

Inherits:
Object
  • Object
show all
Defined in:
lib/yobi/restic_output.rb,
sig/yobi.rbs

Overview

:nodoc:

Defined Under Namespace

Classes: LazyList

Constant Summary collapse

DEFAULT_TAIL_CHUNK_SIZE =

Returns:

  • (Integer)
4096

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tail_chunk_size: DEFAULT_TAIL_CHUNK_SIZE, transform: nil) ⇒ ResticOutput

Returns a new instance of ResticOutput.

Parameters:

  • tail_chunk_size: (Integer) (defaults to: DEFAULT_TAIL_CHUNK_SIZE)
  • transform: (^(Hash[String, untyped]) -> untyped) (defaults to: nil)


12
13
14
15
16
17
18
19
# File 'lib/yobi/restic_output.rb', line 12

def initialize(tail_chunk_size: DEFAULT_TAIL_CHUNK_SIZE, transform: nil)
  @file = Tempfile.new("yobi-restic-output")
  @file.unlink
  @tail_chunk_size = tail_chunk_size
  @transform = transform
  @index = nil
  @stderr_offsets = []
end

Instance Attribute Details

#fileFile (readonly)

Returns the value of attribute file.

Returns:

  • (File)


10
11
12
# File 'lib/yobi/restic_output.rb', line 10

def file
  @file
end

Instance Method Details

#each_linevoid #each_lineEnumerator[String, void]

Overloads:

  • #each_linevoid

    This method returns an undefined value.

  • #each_lineEnumerator[String, void]

    Returns:

    • (Enumerator[String, void])

Yields:

Yield Parameters:

  • line (String)

Yield Returns:

  • (void)


49
50
51
52
53
54
# File 'lib/yobi/restic_output.rb', line 49

def each_line(&block)
  return enum_for(:each_line) unless block_given?

  @file.rewind
  @file.each_line(&block)
end

#indexHash[String, Array[Integer]]

Returns:

  • (Hash[String, Array[Integer]])


21
22
23
# File 'lib/yobi/restic_output.rb', line 21

def index
  @index ||= build_index
end

#inspectObject



94
95
96
# File 'lib/yobi/restic_output.rb', line 94

def inspect
  "#<#{self.class} #{@file.size} bytes>"
end

#last_lineString?

Returns:

  • (String, nil)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/yobi/restic_output.rb', line 30

def last_line
  size = @file.size
  return nil if size.zero?

  window = @tail_chunk_size
  loop do
    read_size = [window, size].min
    @file.seek(size - read_size)
    lines = @file.read(read_size).each_line.to_a
    lines.shift if read_size < size

    line = lines.reverse_each.find { |candidate| !candidate.strip.empty? }
    return line.strip if line
    return nil if read_size == size

    window *= 2
  end
end

#messagesvoid #messages(message_type) ⇒ Enumerator[Hash[String, untyped], void]

Overloads:

  • #messagesvoid

    This method returns an undefined value.

  • #messages(message_type) ⇒ Enumerator[Hash[String, untyped], void]

    Parameters:

    • message_type (String, nil)

    Returns:

    • (Enumerator[Hash[String, untyped], void])


56
57
58
59
60
61
62
# File 'lib/yobi/restic_output.rb', line 56

def messages(message_type = nil, &transform)
  transform ||= @transform
  return raw_messages(message_type) unless transform

  offsets = message_type ? index[message_type] : index.values.flatten.sort
  LazyList.new(self, offsets, transform)
end

#read_line_at(offset) ⇒ String

Parameters:

  • offset (Integer)

Returns:

  • (String)


25
26
27
28
# File 'lib/yobi/restic_output.rb', line 25

def read_line_at(offset)
  @file.seek(offset)
  @file.gets
end

#stderr_linesvoid #stderr_linesEnumerator[String, void]

Overloads:

  • #stderr_linesvoid

    This method returns an undefined value.

  • #stderr_linesEnumerator[String, void]

    Returns:

    • (Enumerator[String, void])

Yields:

Yield Parameters:

  • line (String)

Yield Returns:

  • (void)


64
65
66
67
68
# File 'lib/yobi/restic_output.rb', line 64

def stderr_lines
  return enum_for(:stderr_lines) unless block_given?

  @stderr_offsets.each { |offset| yield read_line_at(offset) }
end

#to_sObject



89
90
91
92
# File 'lib/yobi/restic_output.rb', line 89

def to_s
  @file.rewind
  @file.read
end

#write_and_parse(line, origin) ⇒ Object

Parameters:

  • line (String)
  • origin (:stdout, :stderr)

Returns:

  • (Object)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/yobi/restic_output.rb', line 70

def write_and_parse(line, origin)
  offset = @file.pos
  @file.write(line)

  parsed = begin
    JSON.parse(line)
  rescue JSON::ParserError
    nil
  end

  if parsed
    (@index ||= Hash.new { |hash, message_type| hash[message_type] = [] })[parsed["message_type"]] << offset if parsed["message_type"]
    @transform ? @transform.call(parsed) : parsed
  elsif origin == :stderr
    @stderr_offsets << offset
    nil
  end
end