RCR 328: Provide Kernel method for platform-agnostic script launching
Submitted by headius (Thu Feb 23 18:59:34 UTC 2006)
Abstract
Currently, many Ruby applications launch additional Ruby scripts in external processes, usually by calling Kernel#system or using backquotes. In order to support future MVM efforts and avoid platform-specific hacks, Ruby should provide a Kernel method to launch Ruby scripts.
Problem
Many scripts today launch external Ruby scripts using Kernel#system or backquotes (and perhaps other ways). This causes Ruby to always launch a new process to run a script, which can be very heavy-weight on some platforms. It sometimes requires platform tricks to know the appropriate way to launch the Ruby executable and to handle differences in path or executable name. Finally, it limits Ruby's deployability in environments where process launching is limited or where multi-VM capabilities could replace multiple process launches.
Proposal
Since it has been stated that multi-VM capabilities are in Ruby's future, and since at least one alternative implementation (JRuby) supports MVM today, I propose adding a Kernel method to launch Ruby scripts in a platform-independent way, allowing the underlying implementation to choose how that script should be launched.
Naming is important, but not my decision. Anything akin to Kernel#run_script would suit me fine. The important point is having a core method you can call to launch a new script in a platform and implementation-independent way, without mucking about with filesystem paths and executable names.
Analysis
Existing methods for launching external processes are generic across all possible executions. A new method is required for the very common scenario where one script wants to launch another. By providing such a method and recommending its use for executing external Ruby scripts, future implementations will have more flexibility to launch those scripts in more suitable ways (like launching a new Ruby VM in the same process).
Implementation
The implementation in 1.8.* would simply defer to Kernel#system, since 1.8 does not support MVM. When MVM is available in the future, launching in the same process could be possible, and those future versions could enable it.
My Ruby is not very strong, but here is some basic pseudoruby for 1.8.*:
class Kernel
def Kernel.run_script(script, args)
if ruby supports MVM
MVM.launch(script, args)
else
Kernel.system(<ruby executable> + script + args)
end
end
end
The important point is that this new method allows the underlying implementation to choose how to launch the script, rather than requiring everyone to exec external processes.
How does this differ from Kernel#load?
Kernel#load runs the script in the current process and the current runtime, which could change things about that process or runtime. Typically apps want to launch scripts out-of-process to ensure they are isolated and separate from the launching process and from each other. This is accomplished now by spawning a separate ruby process, but in the future could be accomplished by launching a separate ruby runtime (VM) within the same process. Either way there should be a single function for running a ruby script in an isolated environment. - headius
I like this idea and hopefully we can get Ruby 1.8 to support it through the sandbox. - _why
|
Strongly opposed |
1 |
Opposed |
0 |
Neutral |
0 |
In favor |
3 |
Strongly advocate |
4 |
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
Kernel#load runs the script in the current process and the current runtime, which could change things about that process or runtime. Typically apps want to launch scripts out-of-process to ensure they are isolated and separate from the launching process and from each other. This is accomplished now by spawning a separate ruby process, but in the future could be accomplished by launching a separate ruby runtime (VM) within the same process. Either way there should be a single function for running a ruby script in an isolated environment. - headius
I like this idea and hopefully we can get Ruby 1.8 to support it through the sandbox. - _why