Class: Spring

Inherits:
Object
  • Object
show all
Defined in:
lib/spring.rb,
lib/spring/env.rb,
lib/spring/sid.rb,
lib/spring/server.rb,
lib/spring/version.rb,
lib/spring/commands.rb,
lib/spring/application.rb,
lib/spring/application_manager.rb,
lib/spring/application_watcher.rb

Defined Under Namespace

Modules: Commands, SID Classes: Application, ApplicationManager, ApplicationWatcher, Env, Server

Constant Summary collapse

SERVER_COMMAND =
[
  File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')),
  "-r", "bundler/setup",
  "-r", "spring/server",
  "-e", "Spring::Server.boot"
]
FORWARDED_SIGNALS =
%w(INT QUIT USR1 USR2 INFO)
IGNORE_SIGNALS =
%w(INT QUIT)
VERSION =
"0.0.4"

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSpring

Returns a new instance of Spring.



26
27
28
# File 'lib/spring.rb', line 26

def initialize
  @env = Env.new
end

Class Attribute Details

.application_watcherObject

Returns the value of attribute application_watcher.



7
8
9
# File 'lib/spring/application.rb', line 7

def application_watcher
  @application_watcher
end

.commandsObject (readonly)

Returns the value of attribute commands.



5
6
7
# File 'lib/spring/commands.rb', line 5

def commands
  @commands
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



24
25
26
# File 'lib/spring.rb', line 24

def env
  @env
end

Class Method Details

.command(name) ⇒ Object



12
13
14
# File 'lib/spring/commands.rb', line 12

def self.command(name)
  commands.fetch name
end

.register_command(name, klass) ⇒ Object



8
9
10
# File 'lib/spring/commands.rb', line 8

def self.register_command(name, klass)
  commands[name] = klass.new
end

.run(args) ⇒ Object



20
21
22
# File 'lib/spring.rb', line 20

def self.run(args)
  exit new.run(args)
end

Instance Method Details

#boot_serverObject

Boot the server into the process group of the current session. This will cause it to be automatically killed once the session ends (i.e. when the user closes their terminal).



47
48
49
50
51
# File 'lib/spring.rb', line 47

def boot_server
  env.socket_path.unlink if env.socket_path.exist?
  Process.spawn(*SERVER_COMMAND, pgroup: SID.pgid)
  sleep 0.1 until env.socket_path.exist?
end

#run(args) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/spring.rb', line 53

def run(args)
  boot_server unless server_running?

  application, client = UNIXSocket.pair

  server = UNIXSocket.open(env.socket_name)
  server.send_io client
  server.puts rails_env_for(args.first)

  application.send_io STDOUT
  application.send_io STDERR
  application.send_io stdin_slave

  application.puts args.length

  args.each do |arg|
    application.puts  arg.length
    application.write arg
  end

  pid = server.gets.chomp

  # We must not close the client socket until we are sure that the application has
  # received the FD. Otherwise the FD can end up getting closed while it's in the server
  # socket buffer on OS X. This doesn't happen on Linux.
  client.close

  if pid.empty?
    false
  else
    forward_signals(pid.to_i)
    application.read # FIXME: receive exit status from server
    true
  end
rescue Errno::ECONNRESET
  false
ensure
  application.close if application
  server.close if server
end

#server_running?Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/spring.rb', line 30

def server_running?
  if env.pidfile_path.exist?
    pidfile = env.pidfile_path.open('r')
    !pidfile.flock(File::LOCK_EX | File::LOCK_NB)
  else
    false
  end
ensure
  if pidfile
    pidfile.flock(File::LOCK_UN)
    pidfile.close
  end
end