On Nov 23, 2009, at 10:32 AM, Eric Wong wrote:
> evanphx <[email protected]> wrote:
>> Hi Eric!
>>
>> Thanks for giving Rubinius a ride on the Unicorn. Sounds like you're
>> using a lot of features that we probably haven't yet sussed the bugs
>> out of, I'll address them more below.
>>
>> On Nov 22, 12:18 am, Eric Wong <[email protected]> wrote:
>>> Hi all,
>>> Since I'm already short on time/resources and unfamiliar with Rubinius
>>> internals (or C++), but I thought you guys might be interested in
>>> getting Unicorn to run under Rubinius since all the currently failing
>>> parts are still pure Ruby, just not commonly-used Ruby.
>>
>> Yeah, it sounds like you're hitting some behavior right at the edge of
>> a bunch of classes. It's pretty likely we haven't yet hit this (no
>> specs for it). Any of these behaviors though it would be great if you
>> could write rubyspecs for. That would make it super easy for us to see
>> your expectations for the behavior and have an isolated test case.
>
> OK, it might take me a few days to find time to get familiar with
> rubyspecs (the spec DSL weirds me out a bit). I'll be sure to let you
> guys know if/when I get around to it.
>
>>> Unicorn does a lot of Unix-only things that are uncommon in most Ruby
>>> code:
>>>
>>> * Working with unlinked Files (empty ones are also shared across
>>> parent+child and we do fchmod() on them). We also buffer
>>> large uploads to unlinked File objects. This seems to fail
>>> immediately at startup once the master forks off the worker
>>> since each worker gets a file descriptor it shares with
>>> the master.
>>
>> This does not happen on MRI? Child processes to share file descriptors
>> (and thusly unix kernel file objects) with the parent, so this is how
>> I'd expect it to work. What behavior are you expecting?
>
> Actually, File#stat seems to be failing in the parent, and I don't even
> need fork to reproduce it. I just reproduced this while zoning out in a
> meeting:
>
> ------------------------------- 8< ----------------------------
> require 'tempfile'
>
> files = (1..10).map do
> fp = Tempfile.new(nil)
> File.unlink(fp.path)
> fp
> end
> puts 'starting stat loop'
>
> loop do
> files.each do |fp|
> p [ fp.path, fp.stat ]
> end
> end
> ------------------------------- 8< ----------------------------
> $ ./bin/rbx t.unlinked.rb
> starting stat loop
> An exception occurred running t.unlinked.rb
> No such file or directory - No such file or directory -
> /tmp/20091123-20573-1nogd72-0 (ENOENT)
>
> Backtrace:
> Errno.handle at kernel/common/errno.rb:24
> File::Stat#initialize at kernel/common/file.rb:915
> File#stat at kernel/common/file.rb:805
> #<Class:0x2ac>(Tempfile)#stat at (eval):2
> main.__script__ {} at t.unlinked.rb:12
> Array#each at kernel/bootstrap/array.rb:156
> main.__script__ at t.unlinked.rb:11
> Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:230
> Requirer::Utils.single_load at kernel/delta/requirer.rb:236
> Requirer::Utils.load_from_extension at kernel/delta/requirer.rb:321
> Rubinius::Loader#script at kernel/loader.rb:334
> Rubinius::Loader#main at kernel/loader.rb:448
> Object#__script__ at kernel/loader.rb:452
> ------------------------------- 8< ----------------------------
>
> I'm running 0.13 on Debian GNU/Linux stable, x86_64
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.
>
>>> * 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).
>
> 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.
As I said, this has serious problems though because what keeps you from
screwing up non-log files?
>
> ref: http://git.bogomips.org/cgit/unicorn.git/tree/lib/unicorn/util.rb
>
>>> * Signal handlers, I keep them short and process them later in
>>> the main event loops. test_signals.rb seems to get bogged
>>> down and weird, and test_exec.rb is basically shell script
>>> written in Ruby.
>>
>> We haven't pushed hard on Signal handlers, I'll take a look at this.
>
> Cool.
>
>> Sounds like we should be able to get this sorted out, just need a bit
>> more info on the questions I've asked above.
>
> Thanks!
>
> --
> Eric Wong
>
> --
> --- !ruby/object:MailingList
> name: rubinius-dev
> view: http://groups.google.com/group/rubinius-dev?hl=en
> post: [email protected]
> unsubscribe: [email protected]
>
--
--- !ruby/object:MailingList
name: rubinius-dev
view: http://groups.google.com/group/rubinius-dev?hl=en
post: [email protected]
unsubscribe: [email protected]