Forum: Ruby Block method to yield stdout?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
990bf71a4e84e1145a3131f35656dc18?d=identicon&s=25 List Rb (listx300108u79872)
on 2008-10-20 20:21
(Received via mailing list)
All, I've written a distribution service that spawns processes using
IO.popen in a seperate thread for each job.

In my Task class, I would like to create a block method such as
'Task.monitor(mode="stdout")', which would yield the stdout for that
task from that point forward. -- similar to tail -f, but for a
multithreaded environment.

The result would in essence be called like:

task = Task.new(:cmd => "tail -f /some/log")
sleep 10
task.monitor
# fresh content from some/log will be yielded


Since $stdout is global, what would be the beat way tackle this?
134ea397777886d6f0aa992672a50eaa?d=identicon&s=25 Mark Thomas (Guest)
on 2008-10-20 23:15
(Received via mailing list)
On Oct 20, 2:19 pm, "List.rb" <list...@gmail.com> wrote:

> In my Task class, I would like to create a block method such as  
> 'Task.monitor(mode="stdout")', which would yield the stdout for that  
> task from that point forward. -- similar to tail -f

Have you seen File::Tail?
http://file-tail.rubyforge.org/doc/index.html

-- Mark.
990bf71a4e84e1145a3131f35656dc18?d=identicon&s=25 List Rb (listx300108u79872)
on 2008-10-21 04:44
(Received via mailing list)
On Mon, Oct 20, 2008 at 5:13 PM, Mark Thomas <mark@thomaszone.com>
wrote:

>
>
Thanks Mark for replying. Yes I have used Tail before but what I'm
looking
for is more along the lines of a non-blocking version of IO#readlines

Currently, I do this on the server side:

def spawn(job)
   task = Task.new(job)
   queue = Queue.new
   Thread.new(queue) {|q|
       pipe = IO.popen(task.job.cmd)
       q.push(pipe)
       q.push(pipe.pid)
       task.pid = pipe.pid
       begin
           Thread.new {
             task.output = pipe.readlines
             pipe.close
             task.exitstatus = $?.exitstatus
             task.history << {:completed => Time.now}
           }
        rescue => e
            q.push e
       end
    }
    queue.clear
    self.tasks.push(task)
    return task
end

Since IO#readlines blocks, I am not sure how to tap into the process
output
:-(

Thanks again
851acbab08553d1f7aa3eecad17f6aa9?d=identicon&s=25 Ken Bloom (Guest)
on 2008-10-23 02:41
(Received via mailing list)
On Mon, 20 Oct 2008 13:19:56 -0500, List.rb wrote:

> task = Task.new(:cmd => "tail -f /some/log") sleep 10
> task.monitor
> # fresh content from some/log will be yielded
>
>
> Since $stdout is global, what would be the beat way tackle this?

Maybe use Open3, or popen. Worst case, look at how Open3 does a
fork/exec
to call the appropriate program.

--Ken
This topic is locked and can not be replied to.