Class: OneApm::Support::ForkedProcessChannel::Pipe

Inherits:
Object
  • Object
show all
Defined in:
lib/one_apm/support/forked_process_channel.rb

Constant Summary collapse

READY_MARKER =
"READY"
NUM_LENGTH_BYTES =
4

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePipe

Returns a new instance of Pipe.



30
31
32
33
34
35
36
37
# File 'lib/one_apm/support/forked_process_channel.rb', line 30

def initialize
  @out, @in = IO.pipe
  if defined?(::Encoding::ASCII_8BIT)
    @in.set_encoding(::Encoding::ASCII_8BIT)
  end
  @last_read = Time.now
  @parent_pid = $$
end

Instance Attribute Details

#inObject

Returns the value of attribute in.



27
28
29
# File 'lib/one_apm/support/forked_process_channel.rb', line 27

def in
  @in
end

#last_readObject (readonly)

Returns the value of attribute last_read.



28
29
30
# File 'lib/one_apm/support/forked_process_channel.rb', line 28

def last_read
  @last_read
end

#outObject

Returns the value of attribute out.



27
28
29
# File 'lib/one_apm/support/forked_process_channel.rb', line 27

def out
  @out
end

#parent_pidObject (readonly)

Returns the value of attribute parent_pid.



28
29
30
# File 'lib/one_apm/support/forked_process_channel.rb', line 28

def parent_pid
  @parent_pid
end

Instance Method Details

#after_fork_in_childObject



81
82
83
84
# File 'lib/one_apm/support/forked_process_channel.rb', line 81

def after_fork_in_child
  @out.close unless @out.closed?
  write(READY_MARKER)
end

#after_fork_in_parentObject



86
87
88
# File 'lib/one_apm/support/forked_process_channel.rb', line 86

def after_fork_in_parent
  @in.close unless @in.closed?
end

#closeObject



39
40
41
42
# File 'lib/one_apm/support/forked_process_channel.rb', line 39

def close
  @out.close unless @out.closed?
  @in.close unless @in.closed?
end

#closed?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/one_apm/support/forked_process_channel.rb', line 90

def closed?
  @out.closed? && @in.closed?
end

#deserialize_message_length(data) ⇒ Object



48
49
50
# File 'lib/one_apm/support/forked_process_channel.rb', line 48

def deserialize_message_length(data)
  data.unpack("L>").first
end

#eof?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/one_apm/support/forked_process_channel.rb', line 77

def eof?
  !@out.closed? && @out.eof?
end

#readObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/one_apm/support/forked_process_channel.rb', line 58

def read
  @in.close unless @in.closed?
  @last_read = Time.now
  length_bytes = @out.read(NUM_LENGTH_BYTES)
  if length_bytes
    message_length = deserialize_message_length(length_bytes)
    if message_length
      @out.read(message_length)
    else
      length_hex = length_bytes.bytes.map { |b| b.to_s(16) }.join(' ')
      OneApm::Manager.logger.error("Failed to deserialize message length from pipe. Bytes: [#{length_hex}]")
      nil
    end
  else
    OneApm::Manager.logger.error("Failed to read bytes for length from pipe.")
    nil
  end
end

#serialize_message_length(data) ⇒ Object



44
45
46
# File 'lib/one_apm/support/forked_process_channel.rb', line 44

def serialize_message_length(data)
  [data.bytesize].pack("L>")
end

#write(data) ⇒ Object



52
53
54
55
56
# File 'lib/one_apm/support/forked_process_channel.rb', line 52

def write(data)
  @out.close unless @out.closed?
  @in << serialize_message_length(data)
  @in << data
end