I've got an issue with Ruby. Specifically, the spawn()
and fork()
methods.
I'm developing a website using Nanoc on Windows, and upon trying to implement the nanoc-live
gem, I get the message that fork()
is unimplemented on this machine.
Upon researching what I could about this, the only thing I really came back with, was to replace it with spawn()
. However, I don't know Ruby. And the nanoc-live documentation is down. I have asked on what support forums they have with no luck.
I don't ask how to do this lightly because I like figuring out issues but this has me stumped, and I'm hardly a Ruby dev. How would I replace the below method call so it uses spawn()
? Or, if someone has a different solution in their back pocket, that would also be great.
Ruby version 3.2.2
Nanoc version 4.12.15
Windows 10
This is the offending method
def run_parent
# create initial child
pipe_read, pipe_write = IO.pipe
fork { run_child(pipe_write, pipe_read) { |s| yield(s) } } Here is the method call
pipe_read.close
changes = gen_lib_changes
puts 'Listening for lib/ changes…'
changes.each do |_e|
# stop child
pipe_write.write('q')
pipe_write.close
Process.wait
# create new child
pipe_read, pipe_write = IO.pipe
fork { run_child(pipe_write, pipe_read) { |s| yield(s) } }
pipe_read.close
end
rescue Interrupt
end
And this is the run_child method called by fork()
def run_child(pipe_write, pipe_read)
pipe_write.close
site = Nanoc::Core::SiteLoader.new.new_from_cwd
changes_enum = gen_changes_for_child(site)
yield(site)
quit = Object.new
parent_enum = Enumerator.new do |y|
pipe_read.read
y << quit
end
puts 'Listening for site changes…'
SlowEnumeratorTools.merge([parent_enum, changes_enum]).each do |e|
break if quit.equal?(e)
$stderr.print 'Reloading site… '
$stderr.flush
site_loader = Nanoc::Core::SiteLoader.new
site = Nanoc::Core::Site.new(
config: Nanoc::Core::ConfigLoader.new.new_from_cwd,
data_source: site_loader.gen_data_source_for_config(site.config),
code_snippets: site.code_snippets,
)
$stderr.puts 'done'
yield(site)
end
exit 0
rescue Interrupt
exit 0
end
Thanks In Advance.
You can use spawn like this to achieve what you want. However, as the answer details, process spawning like this in Windows is not optimal. You should consider threads.