spring 0.9.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/spring/env.rb CHANGED
@@ -1,18 +1,30 @@
1
1
  require "pathname"
2
2
  require "fileutils"
3
+ require "digest/md5"
4
+ require "tmpdir"
3
5
 
4
6
  require "spring/version"
5
7
  require "spring/sid"
8
+ require "spring/configuration"
6
9
 
7
10
  module Spring
8
11
  IGNORE_SIGNALS = %w(INT QUIT)
9
12
 
10
13
  class Env
11
- attr_reader :root, :log_file
14
+ attr_reader :log_file
12
15
 
13
16
  def initialize(root = nil)
14
- @root = root || Pathname.new(File.expand_path('.'))
15
- @log_file = File.open(ENV["SPRING_LOG"] || "/dev/null", "a")
17
+ @root = root
18
+ @project_root = root
19
+ @log_file = File.open(ENV["SPRING_LOG"] || "/dev/null", "a")
20
+ end
21
+
22
+ def root
23
+ @root ||= Spring.application_root_path
24
+ end
25
+
26
+ def project_root
27
+ @project_root ||= Spring.project_root_path
16
28
  end
17
29
 
18
30
  def version
@@ -20,13 +32,17 @@ module Spring
20
32
  end
21
33
 
22
34
  def tmp_path
23
- path = default_tmp_path
35
+ path = Pathname.new(Dir.tmpdir + "/spring")
24
36
  FileUtils.mkdir_p(path) unless path.exist?
25
37
  path
26
38
  end
27
39
 
40
+ def application_id
41
+ Digest::MD5.hexdigest(project_root.to_s)
42
+ end
43
+
28
44
  def socket_path
29
- tmp_path.join("spring")
45
+ tmp_path.join(application_id)
30
46
  end
31
47
 
32
48
  def socket_name
@@ -34,7 +50,7 @@ module Spring
34
50
  end
35
51
 
36
52
  def pidfile_path
37
- tmp_path.join("spring.pid")
53
+ tmp_path.join("#{application_id}.pid")
38
54
  end
39
55
 
40
56
  def pid
@@ -49,7 +65,7 @@ module Spring
49
65
  end
50
66
 
51
67
  def server_running?
52
- pidfile = pidfile_path.open('r')
68
+ pidfile = pidfile_path.open('r+')
53
69
  !pidfile.flock(File::LOCK_EX | File::LOCK_NB)
54
70
  rescue Errno::ENOENT
55
71
  false
@@ -60,23 +76,9 @@ module Spring
60
76
  end
61
77
  end
62
78
 
63
- def bundle_mtime
64
- [Bundler.default_lockfile, Bundler.default_gemfile].select(&:exist?).map(&:mtime).max
65
- end
66
-
67
79
  def log(message)
68
- log_file.puts "[#{Time.now}] #{message}"
80
+ log_file.puts "[#{Time.now}] [#{Process.pid}] #{message}"
69
81
  log_file.flush
70
82
  end
71
-
72
- private
73
-
74
- def default_tmp_path
75
- if ENV['SPRING_TMP_PATH']
76
- Pathname.new(ENV['SPRING_TMP_PATH'])
77
- else
78
- root.join('tmp/spring')
79
- end
80
- end
81
83
  end
82
84
  end
data/lib/spring/errors.rb CHANGED
@@ -15,20 +15,6 @@ module Spring
15
15
  end
16
16
  end
17
17
 
18
- class TmpUnwritable < StandardError
19
- attr_reader :tmp_path
20
-
21
- def initialize(tmp_path)
22
- @tmp_path = tmp_path
23
- end
24
-
25
- def message
26
- "Spring is unable to create a socket file at #{tmp_path}. You may need to " \
27
- "set the SPRING_TMP_PATH environment variable to use a different path. See " \
28
- "the documentation for details."
29
- end
30
- end
31
-
32
18
  class MissingApplication < ClientError
33
19
  attr_reader :project_root
34
20
 
data/lib/spring/server.rb CHANGED
@@ -1,19 +1,13 @@
1
- require "socket"
2
- require "thread"
1
+ module Spring
2
+ ORIGINAL_ENV = ENV.to_hash
3
+ end
3
4
 
4
- require "spring/configuration"
5
- require "spring/env"
5
+ require "spring/boot"
6
6
  require "spring/application_manager"
7
- require "spring/process_title_updater"
8
- require "spring/json"
9
7
 
10
- # Must be last, as it requires bundler/setup
8
+ # Must be last, as it requires bundler/setup, which alters the load path
11
9
  require "spring/commands"
12
10
 
13
- # readline must be required before we setpgid, otherwise the require may hang,
14
- # if readline has been built against libedit. See issue #70.
15
- require "readline"
16
-
17
11
  module Spring
18
12
  class Server
19
13
  def self.boot
@@ -24,7 +18,7 @@ module Spring
24
18
 
25
19
  def initialize(env = Env.new)
26
20
  @env = env
27
- @applications = Hash.new { |h, k| h[k] = ApplicationManager.new(self, k) }
21
+ @applications = Hash.new { |h, k| h[k] = ApplicationManager.new(k) }
28
22
  @pidfile = env.pidfile_path.open('a')
29
23
  @mutex = Mutex.new
30
24
  end
@@ -41,16 +35,12 @@ module Spring
41
35
  ignore_signals
42
36
  set_exit_hook
43
37
  set_process_title
44
- watch_bundle
45
38
  start_server
46
39
  end
47
40
 
48
41
  def start_server
49
42
  server = UNIXServer.open(env.socket_name)
50
43
  log "started on #{env.socket_name}"
51
- rescue Errno::EPERM
52
- raise TmpUnwritable.new(env.tmp_path)
53
- else
54
44
  loop { serve server.accept }
55
45
  end
56
46
 
@@ -78,13 +68,7 @@ module Spring
78
68
  end
79
69
 
80
70
  def rails_env_for(args, default_rails_env)
81
- command = Spring.command(args.first)
82
-
83
- if command.respond_to?(:env)
84
- env = command.env(args.drop(1))
85
- end
86
-
87
- env || default_rails_env
71
+ Spring.command(args.first).env(args.drop(1)) || default_rails_env
88
72
  end
89
73
 
90
74
  # Boot the server into the process group of the current session.
@@ -97,7 +81,7 @@ module Spring
97
81
  # Ignore SIGINT and SIGQUIT otherwise the user typing ^C or ^\ on the command line
98
82
  # will kill the server/application.
99
83
  def ignore_signals
100
- IGNORE_SIGNALS.each { |sig| trap(sig, "IGNORE") }
84
+ IGNORE_SIGNALS.each { |sig| trap(sig, "IGNORE") }
101
85
  end
102
86
 
103
87
  def set_exit_hook
@@ -108,13 +92,13 @@ module Spring
108
92
  end
109
93
 
110
94
  def shutdown
111
- @applications.values.each(&:stop)
112
-
113
95
  [env.socket_path, env.pidfile_path].each do |path|
114
96
  if path.exist?
115
97
  path.unlink rescue nil
116
98
  end
117
99
  end
100
+
101
+ @applications.values.map { |a| Thread.new { a.stop } }.map(&:join)
118
102
  end
119
103
 
120
104
  def write_pidfile
@@ -140,13 +124,5 @@ module Spring
140
124
  "spring server | #{env.app_name} | started #{distance} ago"
141
125
  }
142
126
  end
143
-
144
- def watch_bundle
145
- @bundle_mtime = env.bundle_mtime
146
- end
147
-
148
- def application_starting
149
- @mutex.synchronize { exit if env.bundle_mtime != @bundle_mtime }
150
- end
151
127
  end
152
128
  end
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "0.9.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -22,7 +22,7 @@ module Spring
22
22
  @files = Set.new
23
23
  @directories = Set.new
24
24
  @stale = false
25
- @io_listener = nil
25
+ @listeners = []
26
26
  end
27
27
 
28
28
  def add(*items)
@@ -55,15 +55,14 @@ module Spring
55
55
  @stale
56
56
  end
57
57
 
58
- def mark_stale
59
- @stale = true
60
- @io_listener.write "." if @io_listener
58
+ def on_stale(&block)
59
+ @listeners << block
61
60
  end
62
61
 
63
- def to_io
64
- read, write = IO.pipe
65
- @io_listener = write
66
- read
62
+ def mark_stale
63
+ return if stale?
64
+ @stale = true
65
+ @listeners.each(&:call)
67
66
  end
68
67
 
69
68
  def restart
data/spring.gemspec CHANGED
@@ -10,7 +10,8 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["j@jonathanleighton.com"]
11
11
  gem.description = %q{Rails application preloader}
12
12
  gem.summary = %q{Rails application preloader}
13
- gem.homepage = "http://github.com/jonleighton/spring"
13
+ gem.homepage = "http://github.com/rails/spring"
14
+ gem.license = "MIT"
14
15
 
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }