Evan Phoenix <[email protected]> wrote: > On Nov 23, 2009, at 10:32 AM, Eric Wong wrote: > > evanphx <[email protected]> wrote: > Ah! We're using the wrong stat for File. Here is File#stat: > > def stat > Stat.new @path > end >
> IE, it's going to be using stat(), which since the file is unlinked, > fails. We need to be using fdstat(). Easy fix. Will go in later today. Thanks! > >>> * Iterating through ObjectSpace for File objects with the O_APPEND > >>> flag and File#sync=true, and then doing File#reopen on them. > >>> This seems to fail under test/unit/test_util.rb > >> > >> Zoinks. This sounds like bad news. We don't yet support > >> ObjectSpace#each_object, and even when we do, this code sounds mighty > >> dangerous. You could easily see and manipulate File objects that > >> rubinius kernel is using internally. Why are you doing this? > > > > I was a bit worried at first about it, too, but it's been used pretty > > heavily already with MRI and it seems to work well. > > The problem is it depends on ObjectSpace#each_object, which we don't > have implemented. And when we do implement it, it will be a lot slower > than MRI because of having a moving GC. > > Just had idea actually. We could specifically support > ObjectSpace.each_object(File) by keeping a WeakRef array of all IOs in > the system and pass them up to you when you pass File to each_object. > It's similar to the cheat we use for each_object(Class). That should work. > > > > We need to reopen logs that have been rotated via rename(2) with > > logrotate or similar tools, and we believe copytruncate is evil :> > > > > For $stderr and $stdout it's easy, but for stuff like Rails > > production.log or any application/framework-specific log files, Unicorn > > doesn't know about the File objects for them, so we iterate through > > ObjectSpace > > Hm, so you're trying to support all possible log files without having > to know where to look for them and not requiring an application to > register it's log file with you. A lofty goal. Yup. It's actually not *too* difficult, though. > As I said, this has serious problems though because what keeps you > from screwing up non-log files? We actually check several things and are quite paranoid about it: * fstat(2) != stat(2) (comparing inode + device) * (O_APPEND | O_WRONLY) from fcntl(F_GETFL) * path is absolute * sync=true (Logger sets this) * not closed All of these are potentially racy[1], but rare since Unicorn doesn't do threads. You can check the code here: > > ref: http://git.bogomips.org/cgit/unicorn.git/tree/lib/unicorn/util.rb [1] It could be a problem with Rainbows![2] but in practice I expect log files to be created once when the application is loaded and generally untouched otherwise. People using the built-in rotation functionality in Logger are out of luck, but that functionality is broken in the presence of multiple processes anyways. [2] - Unicorn + multiple levels of craz^H^H^H^Hconcurrency: http://rainbows.rubyforge.org/ -- Eric Wong -- --- !ruby/object:MailingList name: rubinius-dev view: http://groups.google.com/group/rubinius-dev?hl=en post: [email protected] unsubscribe: [email protected]
