这可能很热,因为您在从临时文件中读取时从未真正阻塞。是 POSIX select(2)IO::select上的一个薄层。看起来您正试图阻止直到文件准备好读取,但 select(2) 认为 EOF 已准备好(“文件描述符在文件结束时也已准备好”),因此您总是立即返回from select then call gets 在 EOF 处返回 nil。
您可以获得更真实的 EOF 读取和良好的阻塞行为,方法是避免写入临时文件的线程,而是使用IO::popenfork%x[heroku logs --ps router --tail --app pipewave-cedar]日志尾部,连接到可以循环的 ruby IO 对象,返回gets时退出(指示日志裁缝完成)。当没有可读取的内容时,来自tailer 的管道上的管道将阻塞,并且您的脚本只会在执行行解析和报告时尽可能热地运行。getsnilgets
编辑:我没有设置实际尝试您的代码,但您应该能够用此代码替换日志尾部线程和临时文件读取循环以获得上述行为:
IO.popen( %w{ heroku logs --ps router --tail --app my-heroku-app } ) do |logf|
while line = logf.gets
parse_heroku_line(line) if line =~ /^/
end
end
我还注意到您的报告线程没有做任何事情来同步对@total_lines,等的访问。因此,您有一些较小的竞争条件,您可以从方法更新@total_errors的实例变量中获得不一致的值。parse_heroku_line