When using fork, the child does not update its results. I'm not sure if exec matters, originally I thought it did since it triggers finalization, but more experimenting leads to the conclusion that the child doesn't affect the parent (either one execing is probably totally irrelevant to the other).
Some experiments show the likely cause is that the thread in the producer dies when it forks.
Threads seem to die when forking
# It looks like the reason forked SiB code stops recording is that it kills the thread in the fork
q = Queue.new # => #<Thread::Queue:0x007fe5408fbdf8>
t = Thread.new { # => Thread
while value = q.shift # => :parent, :break
break if value == :break # => false, true
puts "Dequeued #{value.inspect} for (#$$)" # => nil
end # => nil
puts "Thread finished for (#$$)" # => nil
} # => #<Thread:0x007fe5408fb9e8 run>
if fork # => 67750
q << :parent # => #<Thread::Queue:0x007fe5408fbdf8>
puts "Parent (#$$) thread: #{t.inspect}" # => nil
else
q << :child
puts "Child (#$$) thread: #{t.inspect}"
end # => nil
sleep 1 # => 1
q << :break # => #<Thread::Queue:0x007fe5408fbdf8>
t.join # => #<Thread:0x007fe5408fb9e8 dead>
puts "PROCESS (#$$) FINISHED" # => nil
# >> Parent (67749) thread: #<Thread:0x007fe5408fb9e8 run>
# >> Dequeued :parent for (67749)
# >> Child (67750) thread: #<Thread:0x007fe5408fb9e8 dead>
# >> PROCESS (67750) FINISHED
# >> Thread finished for (67749)
# >> PROCESS (67749) FINISHED
File Descriptor is still open for child, results would be recorded if they were being reported
event_stream_fd = Marshal.load(ENV["SIB_VARIABLES.MARSHAL.B64"].unpack('m0').first)[:event_stream_fd] # => 12
stream = nil # => nil
ObjectSpace.each_object(IO) { |io| stream = io if !io.closed? && io.to_i == event_stream_fd } # => 28
# This shows that the FD is still open in the child, it is the thread inside the producer that died
'child will set a result here:' # => "child will set a result here:", Result from child
target_line = __LINE__ - 1 # => 5
if fork # => 68326
# parent is noop
else
line_number = target_line
type = :inspect
inspected = "Result from child"
tokenized = [Marshal.dump(inspected.to_s)].pack('m0')
stream << "result #{line_number} #{type} #{tokenized}\n"
end # => nil
Issue
When using fork, the child does not update its results. I'm not sure if exec matters, originally I thought it did since it triggers finalization, but more experimenting leads to the conclusion that the child doesn't affect the parent (either one execing is probably totally irrelevant to the other).
Cukes to test this behaviour are here.
Some experiments show the likely cause is that the thread in the producer dies when it forks.
Threads seem to die when forking
File Descriptor is still open for child, results would be recorded if they were being reported