tmp8-snailgun 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ If you use ruby-1.9.2-p0 on Snow Leopard snailgun won't work out of the Box!
2
+
3
+ I have included a small patch to the ruby-sources that make it work:
4
+
5
+ (this is assuming you use rvm)
6
+
7
+ cd $HOME/.rvm/src/ruby-1.9.2-p0/ext/socket
8
+ patch -p1 < wherever_snailgun_was_installed/ruby-1.9.2-p0.patch
9
+ ruby extconf.rb
10
+ make clean
11
+ make clean install
12
+
13
+ Patch was taken from http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=29242
14
+
15
+ thieso@gmail.com 20101024
data/README.markdown ADDED
@@ -0,0 +1,217 @@
1
+ Snailgun
2
+ ========
3
+
4
+ Snailgun accelerates the startup of Ruby applications which require large
5
+ numbers of libraries. It does this by preparing a Ruby process with your
6
+ chosen libraries preloaded, and then forking that process whenever a new
7
+ command-line Ruby interpreter is required.
8
+
9
+ Installation
10
+ ------------
11
+
12
+ sudo gem install snailgun
13
+
14
+ Or for the latest code, `git clone git://github.com/candlerb/snailgun.git`
15
+ and put the bin directory into your PATH.
16
+
17
+ Case 1: standalone
18
+ ------------------
19
+
20
+ # WITHOUT SNAILGUN
21
+ $ time ruby -rubygems -e 'require "active_support"' -e 'puts "".blank?'
22
+ true
23
+
24
+ real 0m2.123s
25
+ user 0m1.424s
26
+ sys 0m0.168s
27
+
28
+ # WITH SNAILGUN
29
+ $ snailgun -rubygems -ractive_support
30
+ Snailgun starting on /home/brian/.snailgun/14781 - 'exit' to end
31
+ $ time fruby -e 'puts "".blank?'
32
+ true
33
+
34
+ real 0m0.064s
35
+ user 0m0.020s
36
+ sys 0m0.004s
37
+
38
+ $ exit
39
+ logout
40
+ Snailgun ended
41
+ $
42
+
43
+ Case 2: Rails app
44
+ -----------------
45
+
46
+ When using Rails or Merb, snailgun will start a process preloaded for the
47
+ `test` environment only unless told otherwise.
48
+
49
+ You need to edit `config/environments/test.rb` and set
50
+ `config.cache_classes = false`. This is so that your application classes
51
+ are loaded each time you run a test, rather than being preloaded into
52
+ the test environment.
53
+
54
+ Snailgun will take several seconds to be ready to process requests. Start
55
+ with `snailgun -v` if you wish to be notified when it is ready.
56
+
57
+ $ rails testapp
58
+ $ cd testapp
59
+ $ vi config/environments/test.rb
60
+ ... set config.cache_classes = false
61
+ $ snailgun
62
+ Now entering subshell. Use 'exit' to terminate snailgun
63
+
64
+ $ time RAILS_ENV=test fruby script/runner 'puts 1+2'
65
+ 3
66
+
67
+ real 0m0.169s
68
+ user 0m0.040s
69
+ sys 0m0.008s
70
+
71
+ # To run your test suite
72
+ $ frake test # or frake spec
73
+
74
+ Your preloaded process will remain around until you type `exit` to terminate
75
+ it.
76
+
77
+ Note that any attempt by `fruby` or `frake` to perform an action in an
78
+ environment other than 'test' will fail. See below for how to run multiple
79
+ snailgun environments.
80
+
81
+ Merb support has been contributed (using MERB_ENV), but it is untested by
82
+ me.
83
+
84
+ Case 3: Rails with multiple environments
85
+ ----------------------------------------
86
+
87
+ After reading the warnings below, you may choose to start multiple snailgun
88
+ processes each configured for a different environment, as follows:
89
+
90
+ $ snailgun --rails test,development
91
+
92
+ This gives the potential for faster startup of rake tasks which involve
93
+ the development environment (such as migrations) and the console. The
94
+ utility `fconsole` is provided for this.
95
+
96
+ However, beware that frake and fruby need to decide which of the preloaded
97
+ environments to dispatch the command to. The safest way is to force the
98
+ correct one explicitly:
99
+
100
+ RAILS_ENV=test frake test:units
101
+ RAILS_ENV=development fruby script/server
102
+ RAILS_ENV=test fruby script/runner 'puts "".blank?'
103
+
104
+ If you do not specify the environment, then a simple heuristic is used:
105
+
106
+ * `fruby` always defaults to the 'development' environment.
107
+
108
+ * `frake` honours any `RAILS_ENV=xxx` setting on the command line. If
109
+ missing, `frake` defaults to the 'test' environment if no args are given or
110
+ if an arg containing the word 'test' or 'spec' is given; otherwise it falls
111
+ back to the 'development' environment.
112
+
113
+ WARNING: The decision as to which of the preloaded environments to use is
114
+ made *before* actually running the command. If the wrong choice is made, it
115
+ can lead to problems.
116
+
117
+ In the worst case, you may have a 'test'-type task, but find that it is
118
+ wrongly dispatched to your 'development' environment - and possibly ends up
119
+ blowing away your development database. This actually happened to me while
120
+ developing snailgun. SO IF YOUR DEVELOPMENT DATABASE CONTAINS USEFUL DATA,
121
+ KEEP IT BACKED UP.
122
+
123
+ If you run test files individually, it is especially critical that you set
124
+ the correct environment. e.g.
125
+
126
+ RAILS_ENV=test fruby -Ilib -Itest test/unit/some_test.rb
127
+
128
+ Case 4: Rails with cucumber
129
+ ---------------------------
130
+
131
+ Cucumber creates its own Rails environment called "cucumber", so you can
132
+ setup snailgun like this:
133
+
134
+ $ snailgun --rails test,cucumber
135
+
136
+ Then use `frake cucumber` to exercise the features. frake selects the
137
+ "cucumber" environment if run with "cucumber" as an argument.
138
+
139
+ NOTE: to make your model classes be loaded on each run you need to set
140
+ `config.cache_classes = false` in `config/environments/cucumber.rb`.
141
+ Cucumber will give a big warning saying that this is known to be a
142
+ problem with transactional fixtures. I don't use transactional fixtures
143
+ so this isn't a problem for me.
144
+
145
+ For a substantial performance boost, remove `:lib=>false` lines from
146
+ `config/environments/cucumber.rb` so that cucumber, webrat, nokogiri etc
147
+ are preloaded.
148
+
149
+ Smaller performance boosts can be had from further preloading. For example,
150
+ cucumber makes use of some rspec libraries for diffing even if you're not
151
+ using rspec, so you can preload those. Add something like this to the end of
152
+ `config/environments/cucumber.rb`
153
+
154
+ begin
155
+ require 'spec/expectations'
156
+ require 'spec/runner/differs/default'
157
+ rescue LoadError
158
+ end
159
+ require 'test_help'
160
+ require 'test/unit/testresult'
161
+ require 'active_support/secure_random'
162
+ require 'active_support/time_with_zone'
163
+
164
+ autotest
165
+ --------
166
+
167
+ There is some simple support for autotest (from the ZenTest package).
168
+ Just type `fautotest` instead of `autotest` after snailgun has been started.
169
+ This hasn't been tested for a while.
170
+
171
+ Bypassing rubygems
172
+ ------------------
173
+
174
+ You can get noticeably faster startup if you don't use rubygems to invoke
175
+ the programs. To do this, you can add the binary directory directly into
176
+ the front of your PATH, e.g. for Ubuntu
177
+
178
+ PATH=/var/lib/gems/1.8/gems/snailgun-1.0.3/bin:$PATH
179
+
180
+ Alternatively, create a file called `fruby` somewhere early on in your PATH
181
+ (e.g. under `$HOME/bin`), like this:
182
+
183
+ #!/usr/bin/env ruby
184
+ load '/path/to/the/real/fruby'
185
+
186
+ Repeat for `frake` etc.
187
+
188
+ Other bugs and limitations
189
+ --------------------------
190
+ Only works with Linux/BSD systems, due to use of passing open file
191
+ descriptors across a socket.
192
+
193
+ Ctrl-C doesn't terminate frake processes.
194
+
195
+ `fruby script/console` doesn't give any speedup, because script/console uses
196
+ exec to invoke irb. Use the supplied `fconsole` instead.
197
+
198
+ The environment is not currently passed across the socket to the ruby
199
+ process. This means it's not usable as a fast CGI replacement.
200
+
201
+ In Rails, you need to beware that any changes to your `config/environment*`
202
+ will not be reflected until you stop and restart snailgun.
203
+
204
+ Licence
205
+ -------
206
+ This code is released under the same licence as Ruby itself.
207
+
208
+ Author
209
+ ------
210
+ Brian Candler <B.Candler@pobox.com>
211
+
212
+ Credits:
213
+
214
+ * Jan X <jan.h.xie@gmail.com>
215
+ * George Ogata <george.ogata@gmail.com>
216
+ * Niklas Hofer <niklas+dev@lanpartei.de>
217
+ * Thies C. Arntzen <thieso@gmail.com>
data/bin/fautotest ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+
4
+ # shortcut for: RAILS_ENV=test fruby /path/to/autotest
5
+
6
+ ENV["RAILS_ENV"] = "test"
7
+ Test::Unit.run = true if defined?(Test::Unit) && Test::Unit.respond_to?(:run=)
8
+ ARGV[0,0] = ["-e","gem 'ZenTest'","-e","load Gem.bin_path('ZenTest', 'autotest')","--"]
9
+ load File.join(File.dirname(__FILE__), "fruby")
data/bin/fconsole ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+
4
+ ENV['RAILS_ENV'] = ARGV.shift if ARGV[0] =~ /^\w/
5
+
6
+ ARGV[0,0] = [
7
+ "-rirb",
8
+ "-rirb/completion",
9
+ "-rconsole_app",
10
+ "-rconsole_with_helpers",
11
+ "-eIRB.start", "--", "--simple-prompt"
12
+ ]
13
+ load File.join(File.dirname(__FILE__), "fruby")
data/bin/fcucumber ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+
4
+ $DEFAULT_ENV='cucumber'
5
+ ARGV[0,0] = ['cucumber']
6
+ load File.join(File.dirname(__FILE__), 'fruby')
data/bin/frake ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+ # Here we run rake within a pre-forked ruby process
4
+
5
+ # Pre-parse environment - see collect_tasks in rake/lib/rake.rb
6
+ ARGV.each do |arg|
7
+ if arg =~ /^(\w+)=(.*)$/
8
+ ENV[$1] = $2
9
+ end
10
+ end
11
+
12
+ # Rails/Merb: make a guess at the correct environment
13
+ if File.exist?("config/boot.rb") || File.exist?("config/init.rb")
14
+ if ARGV.find { |arg| arg =~ /\bcucumber\b/ }
15
+ $DEFAULT_ENV='cucumber'
16
+ elsif ARGV.find { |arg| arg =~ /\b(test|spec)\b/ } || !ARGV.find { |arg| arg !~ /^-/ }
17
+ $DEFAULT_ENV='test'
18
+ end
19
+ end
20
+
21
+ ARGV[0,0] = ["-rrake", "-eRake.application.run", "--"]
22
+ load File.join(File.dirname(__FILE__), "fruby")
data/bin/fruby ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+ # This could be rewritten in C for even faster startup
4
+
5
+ require 'lib/snailgun/client'
6
+
7
+ if ENV['SNAILGUN_SOCK']
8
+ sockname = ENV['SNAILGUN_SOCK']
9
+ elsif File.directory?('tmp/sockets/snailgun')
10
+ env = ENV['RAILS_ENV'] || ENV['MERB_ENV']
11
+ unless env
12
+ # Normally default to development: see railties/lib/tasks/misc.rake
13
+ env = $DEFAULT_ENV || 'development'
14
+ STDERR.puts "Snailgun assuming environment '#{env}'"
15
+ end
16
+ sockname = "tmp/sockets/snailgun/#{env}"
17
+ end
18
+
19
+ unless sockname and File.exists? sockname
20
+ STDERR.puts <<EOS
21
+ Unable to find path to snailgun socket.
22
+ - did you run this in a session with a snailgun parent?
23
+ - you can do 'SNAILGUN_SOCK=/path/to/sock #{$0} ...'
24
+ EOS
25
+ exit 1
26
+ end
27
+
28
+ Snailgun::Client.new(sockname)
data/bin/snailgun ADDED
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
3
+
4
+ # Turn on copy-on-write garbage collection in REE: see
5
+ # http://www.rubyenterpriseedition.com/documentation.html#_copy_on_write_friendliness
6
+ begin
7
+ GC.copy_on_write_friendly = true
8
+ rescue NoMethodError
9
+ end
10
+
11
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
12
+ require 'snailgun/server'
13
+ require 'optparse'
14
+
15
+ sockpath = nil
16
+ mode = nil
17
+ envs = "test"
18
+ rake = false
19
+ verbose = false
20
+
21
+ def fix_rake
22
+ require 'rbconfig'
23
+ Config::CONFIG['bindir'] = File.expand_path(File.dirname(__FILE__))
24
+ Config::CONFIG['ruby_install_name'] = 'fruby'
25
+ require 'rubygems'
26
+ require 'rake'
27
+ require 'rake/testtask'
28
+ require 'rake/rdoctask'
29
+ end
30
+
31
+ OptionParser.new do |opts|
32
+ opts.on("-I DIR", "add to load path") { |v| $:.unshift v }
33
+ opts.on("-r LIB", "require library") { |v| require v }
34
+ opts.on("--rails [ENVS]", "rails mode") { |v| mode = :rails; envs = v }
35
+ opts.on("--ruby [SOCKPATH]", "ruby mode") { |v| mode = :ruby; sockpath = v }
36
+ opts.on("--rake", "add rake support") { rake = true }
37
+ opts.on("-v", "--verbose", "show progress") { verbose = true }
38
+ end.parse!
39
+
40
+ mode ||= if File.exist?("config/boot.rb")
41
+ :rails
42
+ elsif File.exist?("config/init.rb")
43
+ :merb
44
+ else
45
+ :ruby
46
+ end
47
+
48
+ STDERR.puts "Starting in #{mode} mode" if verbose
49
+ case mode
50
+ when :ruby
51
+ unless sockpath
52
+ dir = File.join(ENV['HOME'], '.snailgun')
53
+ begin
54
+ Dir.mkdir dir, 0700
55
+ rescue Errno::EEXIST
56
+ File.chmod 0700, dir
57
+ end
58
+ sockpath = File.join dir, $$.to_s
59
+ end
60
+ fix_rake if rake
61
+ server = Snailgun::Server.new(sockpath)
62
+ server.interactive!
63
+
64
+ when :rails
65
+ conf = File.expand_path('config/boot.rb')
66
+ unless File.exist?(conf)
67
+ raise "#{conf} does not exist, cannot continue"
68
+ end
69
+ sockdir = File.expand_path('tmp/sockets/snailgun')
70
+ begin
71
+ Dir.mkdir sockdir, 0700
72
+ rescue Errno::EEXIST
73
+ File.chmod 0700, sockdir
74
+ end
75
+ pids = {}
76
+ fix_rake # TODO: separate process for rake (but then need to choose right RAILS_ENV)
77
+
78
+ start_for_envs = envs.split(/[\s,]+/).uniq
79
+ start_for_envs.each do |env|
80
+ pids[env] = fork do
81
+ STDERR.puts "Server starting for RAILS_ENV=#{env}"
82
+ server = Snailgun::Server.new("#{sockdir}/#{env}")
83
+ ENV['RAILS_ENV'] = env
84
+ load conf
85
+
86
+ if File.exist?('./.snailgun.preload')
87
+ require 'snailgun/require_preload'
88
+ else
89
+ puts "please create a .snailgun.preload by ..."
90
+ end
91
+
92
+ if Rails.respond_to?(:configuration) && Rails.configuration.cache_classes
93
+ STDERR.puts <<-EOS
94
+ WARNING: Snailgun doesn't work well with `cache_classes`. Strongly recommend
95
+ `config.cache_classes = false` in config/environments/#{env}.rb
96
+ EOS
97
+ end
98
+ STDERR.puts "Server ready for RAILS_ENV=#{env}"
99
+ server.run
100
+ end
101
+ end
102
+ if start_for_envs.size == 1
103
+ ENV['RAILS_ENV'] = start_for_envs.first
104
+ STDERR.puts "Now entering subshell for RAILS_ENV=#{ENV['RAILS_ENV']}. Use 'exit' to terminate snailgun"
105
+ else
106
+ STDERR.puts "Now entering subshell Don't forget to set your RAILS_ENV!. Use 'exit' to terminate snailgun"
107
+ end
108
+ Snailgun::Server.shell
109
+ pids.each do |env,pid|
110
+ Process.kill('TERM',pid)
111
+ end
112
+ # TODO: wait a few secs for them to die, 'KILL' if required
113
+ STDERR.puts "Snailgun ended"
114
+
115
+ when :merb
116
+ conf = File.expand_path('config/init.rb')
117
+ unless File.exist?(conf)
118
+ raise '#{conf} does not exist, cannot continue'
119
+ end
120
+ sockdir = File.expand_path('tmp/sockets/snailgun')
121
+ begin
122
+ require 'fileutils'
123
+ FileUtils.mkdir_p sockdir
124
+ ensure
125
+ File.chmod 0700, sockdir
126
+ end
127
+ pids = {}
128
+ fix_rake # TODO: separate process for rake (but then need to choose right RAILS_ENV)
129
+ envs.split(/\s*,\s*/).uniq.each do |env|
130
+ pids[env] = fork do
131
+ server = Snailgun::Server.new("#{sockdir}/#{env}")
132
+ ENV['MERB_ENV'] = env
133
+
134
+ require 'rubygems'
135
+ gem 'merb-core'
136
+ require 'merb'
137
+ Merb.start_environment([env])
138
+
139
+ STDERR.puts "Started server for #{env}" if verbose
140
+ server.run
141
+ end
142
+ end
143
+ STDERR.puts "Use 'exit' to terminate snailgun"
144
+ Snailgun::Server.shell
145
+ pids.each do |env,pid|
146
+ Process.kill('TERM',pid)
147
+ end
148
+ # TODO: wait a few secs for them to die, 'KILL' if required
149
+ STDERR.puts "Snailgun ended"
150
+ end
data/bin/snailgun_ruby ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
3
+ require 'snailgun/client'
4
+
5
+ def rvm_env(path)
6
+ if File.exist?(file = "#{path}/.rvmrc")
7
+ ruby, gemset = IO.read(file).strip.split(" ").last.split("@")
8
+ Dir["#{ENV['rvm_path']}/environments/*#{ruby}*@#{gemset}"].first
9
+ elsif path != "/"
10
+ rvm_env(File.expand_path("#{path}/../"))
11
+ end
12
+ end
13
+
14
+ def snailgun_socket(path)
15
+ if File.socket?(socket = "#{path}/tmp/sockets/snailgun/test")
16
+ socket
17
+ elsif path != "/"
18
+ snailgun_socket(File.expand_path("#{path}/../"))
19
+ end
20
+ end
21
+
22
+ def skip_snailgun?
23
+ ARGV.size == 1 && ARGV[0] =~ /^\/tmp\/cucumber/
24
+ end
25
+
26
+ def log(msg)
27
+ File.open("/tmp/snailgun_ruby.log", "a+") { |f| f.puts msg }
28
+ end
29
+
30
+ cwd = Dir.pwd
31
+
32
+ if !skip_snailgun? && (socket = snailgun_socket(cwd))
33
+ log "fruby #{ARGV.inspect}"
34
+ Snailgun::Client.new(socket)
35
+ else
36
+ if rvm_env = rvm_env(cwd)
37
+ require 'shellwords'
38
+ args = ARGV.map { |a| Shellwords.shellescape(a) }.join(" ")
39
+ log "exec:bash -c 'source #{rvm_env}; ruby #{args}'"
40
+ Kernel.exec('bash', "-c", "source #{rvm_env}; ruby #{args}")
41
+ else
42
+ log "exec:ruby #{ARGV.inspect}\""
43
+ Kernel.exec('ruby', *ARGV)
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ require 'socket'
2
+ module Snailgun
3
+ class Client
4
+ def initialize(sockname)
5
+ server = UNIXSocket.open(sockname)
6
+ server.send_io(STDIN)
7
+ server.send_io(STDOUT)
8
+ server.send_io(STDERR)
9
+ args = Marshal.dump([ARGV, ENV.to_hash, Dir.pwd, Process.getpgrp])
10
+ server.write [args.size].pack("N")
11
+ server.write args
12
+ begin
13
+ rc = (server.read(1) || "\000").unpack("C").first
14
+ exit rc
15
+ rescue Interrupt
16
+ server.write('X')
17
+ exit 1
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ ignore = File.exist?(".snailgun.ignore") ? IO.read(".snailgun.ignore").split : []
2
+ (IO.read(".snailgun.preload") rescue '').split.each do |path|
3
+ next if ignore.include?(path)
4
+ next if path =~ /^#/
5
+ puts "snailgun.preload: #{path}"
6
+ begin
7
+ require path
8
+ rescue Exception => e
9
+ puts "cannot preload:'#{path}' 'cause of:#{e.message}"
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ require 'benchmark'
2
+
3
+ $require_level = 0
4
+ $required = []
5
+
6
+ class SnailgunPreloader
7
+ @@preload_file = "#{File.expand_path(Dir.pwd)}/.snailgun.preload"
8
+
9
+ class << self
10
+ def load_file(path)
11
+ File.exist?(path) ? IO.read(path).split : []
12
+ end
13
+
14
+ def add_to_preload(path)
15
+ ignore = load_file(".snailgun.ignore")
16
+ already_marked_for_preloading = load_file(@@preload_file)
17
+ unless ignore.include?(path) || already_marked_for_preloading.include?(path)
18
+ puts "adding #{path}"
19
+ File.open(@@preload_file, "a+") { |f| f.puts path }
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ module Kernel
26
+ alias require_without_timing require
27
+ def require(path)
28
+ result = seconds = nil
29
+
30
+ begin
31
+ $require_level += 1
32
+ seconds = Benchmark.realtime { result = require_without_timing(path) }
33
+ ensure
34
+ $require_level -= 1
35
+ end
36
+
37
+ if result == true && $require_level == 0
38
+ SnailgunPreloader.add_to_preload(path)
39
+ end
40
+
41
+ # if result
42
+ # puts "R:#{'%.5f' % seconds} #{' '*$require_level}#{path} "
43
+ # end
44
+
45
+ result
46
+ end
47
+ end
48
+
@@ -0,0 +1,132 @@
1
+ # Copyright (C) Brian Candler 2009. Released under the Ruby licence.
2
+
3
+ # Our at_exit handler must be called *last*, so register it first
4
+ at_exit { $SNAILGUN_EXIT.call if $SNAILGUN_EXIT }
5
+
6
+ # Fix truncation of $0. See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/336743
7
+ $progname = $0
8
+ alias $PROGRAM_NAME $0
9
+ alias $0 $progname
10
+ trace_var(:$0) {|val| $PROGRAM_NAME = val} # update for ps
11
+
12
+ require 'socket'
13
+ require 'optparse'
14
+ require 'shellwords'
15
+
16
+ module Snailgun
17
+ class Server
18
+ attr_accessor :sockname
19
+
20
+ def initialize(sockname = nil)
21
+ @sockname = sockname || "/tmp/snailgun#{$$}"
22
+ File.delete(@sockname) rescue nil
23
+ @socket = UNIXServer.open(@sockname)
24
+ yield self if block_given?
25
+ end
26
+
27
+ def run
28
+ while client = @socket.accept
29
+ pid = fork do
30
+ rubylib = nil
31
+ begin
32
+ STDIN.reopen(client.recv_io)
33
+ STDOUT.reopen(client.recv_io)
34
+ STDERR.reopen(client.recv_io)
35
+ nbytes = client.read(4).unpack("N").first
36
+ args, env, cwd, pgid = Marshal.load(client.read(nbytes))
37
+ Dir.chdir(cwd)
38
+ if rubylib = env['RUBYLIB']
39
+ rubylib.split(/:/).each do |path|
40
+ $LOAD_PATH.unshift path
41
+ end
42
+ end
43
+ begin
44
+ Process.setpgid(0, pgid)
45
+ rescue Errno::EPERM
46
+ end
47
+ exit_status = 0
48
+ $SNAILGUN_EXIT = lambda {
49
+ begin
50
+ client.write [exit_status].pack("C")
51
+ rescue Errno::EPIPE
52
+ end
53
+ }
54
+ #This doesn't work in 1.8.6:
55
+ #Thread.new { client.read(1); Thread.main.raise Interrupt }
56
+ Thread.new { client.read(1); exit 1 }
57
+ start_ruby(args)
58
+ rescue SystemExit => e
59
+ exit_status = e.status
60
+ raise # for the benefit of Test::Unit
61
+ rescue Exception => e
62
+ STDERR.puts "#{e}\n\t#{e.backtrace.join("\n\t")}"
63
+ exit 1
64
+ ensure
65
+ $LOAD_PATH.shift if rubylib
66
+ end
67
+ end
68
+ Process.detach(pid) if pid && pid > 0
69
+ client.close
70
+ end
71
+ ensure
72
+ File.delete(@sockname) rescue nil
73
+ end
74
+
75
+ # Process the received ruby command line. (TODO: implement more options)
76
+ def start_ruby(args)
77
+ e = []
78
+ OptionParser.new do |opts|
79
+ opts.on("-e EXPR") do |v|
80
+ e << v
81
+ end
82
+ opts.on("-I DIR") do |v|
83
+ v.split(/:/).each do |path|
84
+ $:.unshift path
85
+ end
86
+ end
87
+ opts.on("-r LIB") do |v|
88
+ require v
89
+ end
90
+ opts.on("--dump_requires") do |v|
91
+ require File.dirname(__FILE__) + "/require_timings.rb"
92
+ end
93
+ opts.on("-KU") do |v|
94
+ $KCODE = 'u' if RUBY_VERSION < "1.9"
95
+ end
96
+ end.order!(args)
97
+
98
+ ARGV.replace(args)
99
+ if !e.empty?
100
+ $0 = '-e'
101
+ e.each { |expr| eval(expr, TOPLEVEL_BINDING) }
102
+ elsif ARGV.empty?
103
+ $0 = '-'
104
+ eval(STDIN.read, TOPLEVEL_BINDING)
105
+ else
106
+ cmd = ARGV.shift
107
+ $0 = cmd
108
+ load(cmd)
109
+ end
110
+ end
111
+
112
+ def self.shell
113
+ shell_opts = ENV['SNAILGUN_SHELL_OPTS']
114
+ args = shell_opts ? Shellwords.shellwords(shell_opts) : []
115
+ system(ENV['SHELL'] || 'bash', *args)
116
+ end
117
+
118
+ # Interactive mode (start a subshell with SNAILGUN_SOCK set up,
119
+ # and terminate the snailgun server when the subshell exits)
120
+ def interactive!
121
+ ENV['SNAILGUN_SOCK'] = @sockname
122
+ pid = Process.fork {
123
+ STDERR.puts "Snailgun starting on #{sockname} - 'exit' to end"
124
+ run
125
+ }
126
+ self.class.shell
127
+ Process.kill('TERM',pid)
128
+ # TODO: wait a few secs for it to die, 'KILL' if required
129
+ STDERR.puts "Snailgun ended"
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,54 @@
1
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: Makefile
2
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: ancdata.o
3
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: basicsocket.o
4
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: constants.o
5
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: constdefs.c
6
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: constdefs.h
7
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: extconf.h
8
+ diff -u socket/extconf.rb /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket/extconf.rb
9
+ --- socket/extconf.rb 2010-05-19 15:48:50.000000000 +0200
10
+ +++ /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket/extconf.rb 2010-10-24 10:44:17.000000000 +0200
11
+ @@ -117,7 +117,7 @@
12
+ }
13
+ end
14
+
15
+ -if (have_func("sendmsg") | have_func("recvmsg")) && /64-darwin/ !~ RUBY_PLATFORM
16
+ +if have_func("sendmsg") | have_func("recvmsg")
17
+ # CMSG_ macros are broken on 64bit darwin, because of use of __DARWIN_ALIGN.
18
+ have_struct_member('struct msghdr', 'msg_control', ['sys/types.h', 'sys/socket.h'])
19
+ have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
20
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: init.o
21
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: ipsocket.o
22
+ Common subdirectories: socket/lib and /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket/lib
23
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: mkmf.log
24
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: option.o
25
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: raddrinfo.o
26
+ diff -u socket/rubysocket.h /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket/rubysocket.h
27
+ --- socket/rubysocket.h 2010-04-28 09:16:30.000000000 +0200
28
+ +++ /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket/rubysocket.h 2010-10-24 10:43:51.000000000 +0200
29
+ @@ -138,6 +138,17 @@
30
+ };
31
+ #endif
32
+
33
+ +#if defined __APPLE__ && defined __MACH__
34
+ +/*
35
+ + * CMSG_ macros are broken on 64bit darwin, because __DARWIN_ALIGN
36
+ + * aligns up to __darwin_size_t which is 64bit, but CMSG_DATA is
37
+ + * 32bit-aligned.
38
+ + */
39
+ +#undef __DARWIN_ALIGNBYTES
40
+ +#define __DARWIN_ALIGNBYTES (sizeof(unsigned int) - 1)
41
+ +#endif
42
+ +
43
+ +
44
+ #if defined(_AIX)
45
+ #ifndef CMSG_SPACE
46
+ # define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
47
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: socket.bundle
48
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: socket.o
49
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: sockssocket.o
50
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: tcpserver.o
51
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: tcpsocket.o
52
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: udpsocket.o
53
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: unixserver.o
54
+ Only in /Users/thieso/.rvm/src/ruby-1.9.2-p0/ext/socket: unixsocket.o
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tmp8-snailgun
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 2
8
+ - 0
9
+ version: 1.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Brian Candler
13
+ - Sebastian Korfmann
14
+ - Thies C. Arntzen
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-12-01 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Snailgun accelerates the startup of Ruby applications which require large numbers of libraries
24
+ email:
25
+ - b.candler@pobox.com
26
+ - dev@tmp8.de
27
+ executables:
28
+ - fautotest
29
+ - fconsole
30
+ - fcucumber
31
+ - frake
32
+ - fruby
33
+ - snailgun
34
+ - snailgun_ruby
35
+ extensions: []
36
+
37
+ extra_rdoc_files:
38
+ - README.markdown
39
+ files:
40
+ - bin/fautotest
41
+ - bin/fconsole
42
+ - bin/fcucumber
43
+ - bin/frake
44
+ - bin/fruby
45
+ - bin/snailgun
46
+ - bin/snailgun_ruby
47
+ - lib/snailgun/server.rb
48
+ - lib/snailgun/require_timings.rb
49
+ - lib/snailgun/client.rb
50
+ - lib/snailgun/require_preload.rb
51
+ - README.markdown
52
+ - README-snowleopard
53
+ - ruby-1.9.2-p0.patch
54
+ has_rdoc: true
55
+ homepage: http://github.com/candlerb/snailgun
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --inline-source
61
+ - --charset=UTF-8
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project: snailgun
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 2
86
+ summary: Command-line startup accelerator
87
+ test_files: []
88
+