Module: Einhorn
- Defined in:
- lib/einhorn.rb,
lib/einhorn/event.rb,
lib/einhorn/client.rb,
lib/einhorn/worker.rb,
lib/einhorn/command.rb,
lib/einhorn/version.rb,
lib/einhorn/worker_pool.rb
Defined Under Namespace
Modules: AbstractState, Command, Event, State, TransientState, Worker, WorkerPool
Classes: Client
Constant Summary
collapse
- VERSION =
'0.3.0'
Class Method Summary
collapse
Class Method Details
.bind(addr, port, flags) ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/einhorn.rb', line 91
def self.bind(addr, port, flags)
log_info("Binding to #{addr}:#{port} with flags #{flags.inspect}")
sd = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
if flags.include?('r') || flags.include?('so_reuseaddr')
sd.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
end
sd.bind(Socket.pack_sockaddr_in(port, addr))
sd.listen(Einhorn::State.config[:backlog])
if flags.include?('n') || flags.include?('o_nonblock')
fl = sd.fcntl(Fcntl::F_GETFL)
sd.fcntl(Fcntl::F_SETFL, fl | Fcntl::O_NONBLOCK)
end
Einhorn::TransientState.socket_handles << sd
sd.fileno
end
|
.is_script(file) ⇒ Object
Not really a thing, but whatever.
153
154
155
156
157
158
|
# File 'lib/einhorn.rb', line 153
def self.is_script(file)
File.open(file) do |f|
bytes = f.read(2)
bytes == '#!'
end
end
|
.log_debug(msg) ⇒ Object
Implement these ourselves so it plays nicely with state persistence
112
113
114
|
# File 'lib/einhorn.rb', line 112
def self.log_debug(msg)
$stderr.puts("#{log_tag} DEBUG: #{msg}") if Einhorn::State.verbosity <= 0
end
|
.log_error(msg) ⇒ Object
118
119
120
|
# File 'lib/einhorn.rb', line 118
def self.log_error(msg)
$stderr.puts("#{log_tag} ERROR: #{msg}") if Einhorn::State.verbosity <= 2
end
|
.log_info(msg) ⇒ Object
115
116
117
|
# File 'lib/einhorn.rb', line 115
def self.log_info(msg)
$stderr.puts("#{log_tag} INFO: #{msg}") if Einhorn::State.verbosity <= 1
end
|
.master_ps_name ⇒ Object
214
215
216
|
# File 'lib/einhorn.rb', line 214
def self.master_ps_name
"einhorn: #{worker_ps_name}"
end
|
.preload ⇒ Object
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
# File 'lib/einhorn.rb', line 160
def self.preload
if path = Einhorn::State.path
set_argv(Einhorn::State.cmd, false)
begin
if !path.end_with?('.rb') && File.exists?(path)
log_info("Loading #{path} (if this hangs, make sure your code can be properly loaded as a library)")
load path
else
log_info("Requiring #{path} (if this hangs, make sure your code can be properly loaded as a library)")
require path
end
rescue Exception => e
log_info("Proceeding with postload -- could not load #{path}: #{e} (#{e.class})\n #{e.backtrace.join("\n ")}")
else
if defined?(einhorn_main)
log_info("Successfully loaded #{path}")
Einhorn::TransientState.preloaded = true
else
log_info("Proceeding with postload -- loaded #{path}, but no einhorn_main method was defined")
end
end
end
end
|
.print_state ⇒ Object
87
88
89
|
# File 'lib/einhorn.rb', line 87
def self.print_state
log_info(Einhorn::State.state.pretty_inspect)
end
|
.restore_state(state) ⇒ Object
.set_argv(cmd, set_ps_name) ⇒ Object
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
# File 'lib/einhorn.rb', line 186
def self.set_argv(cmd, set_ps_name)
idx = 0
if cmd[0] =~ /(^|\/)ruby$/
idx = 1
elsif !is_script(cmd[0])
log_info("WARNING: Going to set $0 to #{cmd[idx]}, but it doesn't look like a script")
end
if set_ps_name
$0 = worker_ps_name
end
ARGV[0..-1] = cmd[idx+1..-1]
log_info("Set#{set_ps_name ? " $0 = #{$0.inspect}, " : nil} ARGV = #{ARGV.inspect}")
end
|
.set_master_ps_name ⇒ Object
210
211
212
|
# File 'lib/einhorn.rb', line 210
def self.set_master_ps_name
$0 = master_ps_name
end
|
.socketify!(cmd) ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/einhorn.rb', line 222
def self.socketify!(cmd)
cmd.map! do |arg|
if arg =~ /^(.*=|)srv:([^:]+):(\d+)((?:,\w+)*)$/
opt = $1
host = $2
port = $3
flags = $4.split(',').select {|flag| flag.length > 0}.map {|flag| flag.downcase}
fd = (Einhorn::State.sockets[[host, port]] ||= bind(host, port, flags))
"#{opt}#{fd}"
else
arg
end
end
end
|
.which(cmd) ⇒ Object
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/einhorn.rb', line 139
def self.which(cmd)
if cmd.include?('/')
return cmd if File.exists?(cmd)
raise "Could not find #{cmd}"
else
ENV['PATH'].split(':').each do |f|
abs = File.join(f, cmd)
return abs if File.exists?(abs)
end
raise "Could not find #{cmd} in PATH"
end
end
|