Class: Rack::Process::Worker

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/process/worker.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_path, input = $stdin, output = $stdout, error = $stderr) ⇒ Worker

Returns a new instance of Worker.



12
13
14
15
16
17
# File 'lib/rack/process/worker.rb', line 12

def initialize config_path, input=$stdin, output=$stdout, error=$stderr
  self.config_path = config_path
  self.input = if input.is_a? String then File.open(input, 'r') else input end
  self.output = if output.is_a? String then File.open(output, 'w') else output end
  self.error = if error.is_a? String then File.open(error, 'w') else error end
end

Instance Attribute Details

#config_pathObject

Returns the value of attribute config_path.



10
11
12
# File 'lib/rack/process/worker.rb', line 10

def config_path
  @config_path
end

#errorObject

Returns the value of attribute error.



10
11
12
# File 'lib/rack/process/worker.rb', line 10

def error
  @error
end

#inputObject

Returns the value of attribute input.



10
11
12
# File 'lib/rack/process/worker.rb', line 10

def input
  @input
end

#outputObject

Returns the value of attribute output.



10
11
12
# File 'lib/rack/process/worker.rb', line 10

def output
  @output
end

Class Method Details

.run(*args) ⇒ Object



6
7
8
# File 'lib/rack/process/worker.rb', line 6

def self.run *args
  new(*args).start
end

Instance Method Details

#appObject



23
24
25
# File 'lib/rack/process/worker.rb', line 23

def app
  @app ||= eval "Rack::Builder.new {( #{config}\n )}.to_app", TOPLEVEL_BINDING, config_path
end

#configObject



19
20
21
# File 'lib/rack/process/worker.rb', line 19

def config
  ::File.read config_path
end

#handle_request(env) ⇒ Object



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
# File 'lib/rack/process/worker.rb', line 59

def handle_request env
  env = {
    "rack.version" => Rack::VERSION,
    "rack.input" => Rack::RewindableInput.new(RackInput.new(self)),
    "rack.errors" => error,
    "rack.multithread" => false,
    "rack.multiprocess" => true,
    "rack.run_once" => false,
    "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
  }.merge(env)

  status, headers, body = app.call env

  write "status"
  write status.to_s
  write "headers"
  write JSON.encode headers
  body.each do |piece|
    write "output"
    write piece
  end
  body.close if body.respond_to? :close
  write "done"
rescue SystemExit, Errno::EINTR
  # Ignore
rescue Exception => e
  write "error"
  write JSON.encode 'name' => e.class.name,
    'message' => e.message,
    'stack' => e.backtrace.join("\n")
end

#readObject



27
28
29
# File 'lib/rack/process/worker.rb', line 27

def read
  NetString.read input
end

#startObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rack/process/worker.rb', line 35

def start
  trap('TERM') { exit }
  trap('INT')  { exit }
  trap('QUIT') { exit }

  input.set_encoding 'ASCII-8BIT' if input.respond_to? :set_encoding

  while not input.eof?
    case command = read
    when "request"
      handle_request JSON.decode read
    when "close"
      exit
    end
  end
rescue SystemExit, Errno::EINTR
  # Ignore
rescue Exception => e
  write "error"
  write JSON.encode 'name' => e.class.name,
    'message' => e.message,
    'stack' => e.backtrace.join("\n")
end

#write(str) ⇒ Object



31
32
33
# File 'lib/rack/process/worker.rb', line 31

def write str
  NetString.write output, str
end