Class: RuVim::Stream::FileLoad

Inherits:
RuVim::Stream show all
Defined in:
lib/ruvim/stream/file_load.rb

Constant Summary collapse

CHUNK_BYTES =
1 * 1024 * 1024
FLUSH_BYTES =
32 * 1024 * 1024

Instance Attribute Summary collapse

Attributes inherited from RuVim::Stream

#state, #stop_handler

Instance Method Summary collapse

Methods inherited from RuVim::Stream

#command, #live?

Constructor Details

#initialize(io:, file_size:, buffer_id:, queue:, stop_handler: nil, &notify) ⇒ FileLoad

Returns a new instance of FileLoad.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ruvim/stream/file_load.rb', line 10

def initialize(io:, file_size:, buffer_id:, queue:, stop_handler: nil, &notify)
  super(stop_handler: stop_handler)
  @io = io
  @state = :live
  @thread = Thread.new do
    pending_bytes = "".b
    ended_with_newline = false
    loaded_bytes = io.pos
    loop do
      chunk = io.readpartial(CHUNK_BYTES)
      next if chunk.nil? || chunk.empty?

      loaded_bytes += chunk.bytesize
      ended_with_newline = chunk.end_with?("\n")
      pending_bytes << chunk
      next if pending_bytes.bytesize < FLUSH_BYTES

      last_nl = pending_bytes.rindex("\n".b)
      if last_nl
        send_bytes = pending_bytes[0..last_nl]
        pending_bytes = pending_bytes[(last_nl + 1)..] || "".b
      else
        send_bytes = pending_bytes
        pending_bytes = "".b
      end
      decoded = Buffer.decode_text(send_bytes)
      parts = decoded.split("\n", -1)
      head = parts.shift || ""
      queue << { type: :file_lines, buffer_id: buffer_id, head: head, lines: parts, loaded_bytes: loaded_bytes, file_size: file_size }
      notify.call
    end
  rescue EOFError
    unless pending_bytes.empty?
      decoded = Buffer.decode_text(pending_bytes)
      parts = decoded.split("\n", -1)
      head = parts.shift || ""
      queue << { type: :file_lines, buffer_id: buffer_id, head: head, lines: parts }
      notify.call
    end
    queue << { type: :file_eof, buffer_id: buffer_id, ended_with_newline: ended_with_newline }
    notify.call
  rescue StandardError => e
    queue << { type: :file_error, buffer_id: buffer_id, error: e.message.to_s }
    notify.call
  ensure
    begin
      io.close unless io.closed?
    rescue StandardError
      nil
    end
  end
end

Instance Attribute Details

#ioObject

Returns the value of attribute io.



8
9
10
# File 'lib/ruvim/stream/file_load.rb', line 8

def io
  @io
end

#threadObject

Returns the value of attribute thread.



8
9
10
# File 'lib/ruvim/stream/file_load.rb', line 8

def thread
  @thread
end

Instance Method Details

#statusObject



63
64
65
66
67
68
# File 'lib/ruvim/stream/file_load.rb', line 63

def status
  case @state
  when :live then "load"
  when :error then "load/error"
  end
end

#stop!Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ruvim/stream/file_load.rb', line 70

def stop!
  io = @io; @io = nil
  begin
    io&.close unless io&.closed?
  rescue StandardError
    nil
  end
  thread = @thread; @thread = nil
  if thread&.alive?
    thread.kill
    thread.join(0.05)
  end
  @state = :closed
end