#!/usr/bin/env ruby

puts Ruby::VERSION

class Wrapper
  class << self
    def finalizer_proc
      proc do |id|
        wrapper_to_ractor = Ractor[:wrapper_to_ractor]

        if wrapper_to_ractor
          begin
            wrapper_to_ractor[id]&.each_key { |ractor| ractor << :close }
          rescue Ractor::ClosedError
            # do nothing
          end
        end
      end
    end

    def setup_finalizer(wrapper)
      wrapper_to_ractor = Ractor[:wrapper_to_ractor] ||= {}
      map = wrapper_to_ractor[wrapper.object_id] ||= {}
      map[wrapper.ractor] = true

      ObjectSpace.define_finalizer(wrapper, &finalizer_proc)
    end
  end

  attr_reader :ractor

  def initialize(object)
    @ractor = Ractor.new do
      loop { break if receive == :close }
    end

    @ractor.send(object, move: true)

    self.class.setup_finalizer(self)
  end
end

class Outer
  def initialize = @inner = Wrapper.new(Inner.new)
end

class Inner; end

GC.start

Wrapper.new(Outer.new)

10.times { GC.start }
