TL;DR: How do you pass execution from within a PTY.spawn block back to
the calling thread long enough to allow the caller to update GUI
elements?
I have a situation that I doubt is particularly unique, but Google
hasn’t been a lot of help, so I thought I’d try you guys as a last
resort. So…to jump right in to it:
I’ve built a front-end GUI for running Cucumber tests using Shoes. All
the app really does is take user selections from the GUI and use them to
string together a command line that I’m then passing in to it’s own
process through a PTY.spawn call.
The point of using the PTY library was to be able to grab the STDOUT
stream of the child process in real time, as per this stack-overflow:
When testing the bare-bones of my code in a terminal, it works
beautifully…the external process is spawned, and I’m able to pull the
stdout of the external process and see it in real time. However, my
situation has the added layer of a GUI. Despite the fact that I’m sure
that the IO pipes are flowing properly, I’m still not getting an update
on my GUI until after the child process terminates.
I’ve done enough reading to understand that this has something to do
with the way Ruby handles thread priority, but I’m having a little bit
of trouble groking a potential solution to my problem. In short, what
I’m looking for is a way to ‘give back’ execution to my GUI process long
enough to let it update itself from the STDOUT output of the child
process.
I hope I was clear enough, but feel free to ask clarifying questions,
and I appreciate any insight!
My code, for reference:
def spawn_command_in_pty(cmd, env, outwindow)
env.each do |k, v|
ENV[k] = v
end
PTY.spawn(cmd) do |r, w, pid|
begin
r.each{|line| outwindow.text = outwindow.text + line }
rescue Errno::EIO => e
raise e
end
end
end
Steve