From: Charles Oliver Nutter Date: 2010-12-22T00:45:28+09:00 Subject: Re: Ruby and science ? On Tue, Dec 21, 2010 at 9:13 AM, James Edward Gray II wrote: > I was once trying to use JRuby in a POSIX environment where I needed Unixy process management.  It had to interoperate with other processes that expected these behaviors.  I ran into at least two challenges and filed the bugs I had seen.  In your replies, you gave me some workarounds and explained why things were purposely working this way.  At this point I realized JRuby was the wrong tool for the job and switched. I think the workarounds were quite acceptable. You did not. That's your prerogative. > My opinion is that Ruby grew up in Unix and it purposely exposes a lot of Unixisms.  I think that means exit!() should kill my process now and exec() should replace my process.  That's what those methods mean to me.  When you give me reasons why that isn't a good idea, it makes me feel like JRuby has stopped trusting me to make the best decisions.  That feels like the Java way, but not the Ruby way, in my opinion. Ruby needs to grow beyond being a Unix-only language. > However, these feelings of mine are not why I said JRuby sucks at process management.  I said it because your exec() doesn't really exec() on purpose.  Your exec() isn't a POSIX exec().  I don't feel that's debatable.  It's just a fact. Ruby's exec isn't a POSIX exec when running on Windows. So it obviously is debatable. > So I'll refine my statement a little:  JRuby sucks at POSIX style process management. How about "JRuby by default does not assume the user wants POSIX-style process management, but does not prevent you from using POSIX-style process management with a bit of extra work." I think it's the "sucks" that I don't like. Just saying something "sucks" because you don't agree with how it does things isn't informative or helpful. In an effort to be more constructive, I present the two bugs in question: Kernel#select() prevents exit during a signal handler http://jira.codehaus.org/browse/JRUBY-5079 JRuby does not do a hard process exit on calls to Kernel#exit because usually the intent is just to stop that Ruby instance. Because JRuby is often running in a shared JVM, doing a hard system exit would frequently kill unrelated services, threads, and other JRuby instances. We opted not to expose a hard system exit specifically for this reason. The bug is that exit can't cause other JVM threads blocking on IO or Java calls to terminate. exec() would be more useful if it really exec()ed http://jira.codehaus.org/browse/JRUBY-5082 Because Kernel#exec also nukes the calling process, we opted (for the same reasons) to have exec not do a "real" system level exec call. Instead, exec launches the process, waits for it to complete, and then raises an internal exception to unroll the execution stack and terminate the JVM. The bug is that the exec'ed process does not have the same pid as the parent, since we launch rather than replace. The workaround for both bugs is fairly simple using FFI: bind the real "exec" and "exit" system calls: https://gist.github.com/579505 We do not do this by default because of the potential for taking down an entire server process (and because at least "exec" does not exist on Windows). If you need this behavior, it's easy to get it. I would also love (with help) to roll this into a gem (or built-in library) that overwrites exec, exit, and similar methods for the purpose of improving POSIX behavior under JRuby. Almost everything "POSIXy" that JRuby "sucks" at can be patched in this way (with the most notable exception being "fork"). You can't please everyone all the time. It's unfortunate that some people think this means you "suck". - Charlie