Class: NewRelic::Agent::PipeChannelManager::Pipe
- Inherits:
-
Object
- Object
- NewRelic::Agent::PipeChannelManager::Pipe
- Defined in:
- lib/new_relic/agent/pipe_channel_manager.rb
Overview
Expected initial sequence of events for Pipe usage:
-
Pipe is created in parent process (read and write ends open)
-
Parent process forks
-
An after_fork hook is invoked in the child
-
From after_fork hook, child closes read end of pipe, and writes a ready marker on the pipe (after_fork_in_child).
-
The parent receives the ready marker, and closes the write end of the pipe in response (after_fork_in_parent).
After this sequence of steps, an exit (whether clean or not) of the child will result in the pipe being marked readable again, and giving an EOF marker (nil) when read. Note that closing of the unused ends of the pipe in the parent and child processes is essential in order for the EOF to be correctly triggered. The ready marker mechanism is used because there’s no easy hook for after_fork in the parent process.
Constant Summary collapse
- READY_MARKER =
"READY"
Instance Attribute Summary collapse
-
#in ⇒ Object
Returns the value of attribute in.
-
#last_read ⇒ Object
readonly
Returns the value of attribute last_read.
-
#out ⇒ Object
Returns the value of attribute out.
-
#parent_pid ⇒ Object
readonly
Returns the value of attribute parent_pid.
Instance Method Summary collapse
- #after_fork_in_child ⇒ Object
- #after_fork_in_parent ⇒ Object
- #close ⇒ Object
- #closed? ⇒ Boolean
-
#initialize ⇒ Pipe
constructor
A new instance of Pipe.
- #read ⇒ Object
- #write(data) ⇒ Object
Constructor Details
#initialize ⇒ Pipe
Returns a new instance of Pipe.
51 52 53 54 55 56 57 58 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 51 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
#in ⇒ Object
Returns the value of attribute in.
48 49 50 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 48 def in @in end |
#last_read ⇒ Object (readonly)
Returns the value of attribute last_read.
49 50 51 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 49 def last_read @last_read end |
#out ⇒ Object
Returns the value of attribute out.
48 49 50 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 48 def out @out end |
#parent_pid ⇒ Object (readonly)
Returns the value of attribute parent_pid.
49 50 51 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 49 def parent_pid @parent_pid end |
Instance Method Details
#after_fork_in_child ⇒ Object
79 80 81 82 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 79 def after_fork_in_child @out.close unless @out.closed? write(READY_MARKER) end |
#after_fork_in_parent ⇒ Object
84 85 86 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 84 def after_fork_in_parent @in.close unless @in.closed? end |
#close ⇒ Object
60 61 62 63 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 60 def close @out.close unless @out.closed? @in.close unless @in.closed? end |
#closed? ⇒ Boolean
88 89 90 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 88 def closed? @out.closed? && @in.closed? end |
#read ⇒ Object
73 74 75 76 77 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 73 def read @in.close unless @in.closed? @last_read = Time.now @out.gets("\n\n") end |
#write(data) ⇒ Object
65 66 67 68 69 70 71 |
# File 'lib/new_relic/agent/pipe_channel_manager.rb', line 65 def write(data) @out.close unless @out.closed? @in << NewRelic::LanguageSupport.with_cautious_gc do Marshal.dump(data) end @in << "\n\n" end |