Class: HQ::Engine::SubProcessRuleProvider

Inherits:
Object
  • Object
show all
Defined in:
lib/hq/engine/subprocess-rule-provider/self.rb,
lib/hq/engine/subprocess-rule-provider/start.rb,
lib/hq/engine/subprocess-rule-provider/session.rb

Defined Under Namespace

Classes: Session

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(req_wr, resp_rd) ⇒ SubProcessRuleProvider

Returns a new instance of SubProcessRuleProvider.



7
8
9
10
11
12
13
14
15
16
# File 'lib/hq/engine/subprocess-rule-provider/self.rb', line 7

def initialize req_wr, resp_rd

  @state = :error

  @req_wr = req_wr
  @resp_rd = resp_rd

  @state = :open

end

Class Method Details

.start(path_to_server) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/hq/engine/subprocess-rule-provider/start.rb', line 5

def self.start path_to_server

  ctl_rd, ctl_wr = IO.pipe
  req_rd, req_wr = IO.pipe
  resp_rd, resp_wr = IO.pipe

  File.executable? path_to_server \
    or raise "Not found: #{path_to_server}"

  # TODO why do we fork twice? i don't think we need to...

  outer_pid = fork do

    at_exit { exit! }

    ctl_rd.close

    inner_pid = fork do

      $stdin.reopen req_rd
      $stdout.reopen resp_wr
      #$stderr.reopen "/dev/null", "w"

      req_rd.close
      resp_wr.close

      exec path_to_server

    end

    ctl_wr.puts inner_pid

    exit!

  end

  ctl_wr.close
  req_rd.close
  resp_wr.close

  inner_pid = ctl_rd.gets.strip.to_i
  ctl_rd.close

  Process.wait outer_pid

  at_exit do
    begin
      Process.kill "TERM", inner_pid
    rescue Errno::ESRCH
      # do nothing
    end
  end

  require "hq/engine/subprocess-rule-provider/self"

  client =
    SubProcessRuleProvider.new \
      req_wr,
      resp_rd

  return client

end

Instance Method Details

#closeObject



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/hq/engine/subprocess-rule-provider/self.rb', line 18

def close

  @state == :open \
    or raise "Invalid state #{@state}"

  @state = :error

  @req_wr.close
  @resp_rd.close

  @state = :closed

end

#perform(request) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/hq/engine/subprocess-rule-provider/self.rb', line 46

def perform request

  @state == :open \
    or raise "Invalid state #{@state}"

  # send request

  request_string =
    MultiJson.dump request

  @req_wr.puts request_string.length + 1
  @req_wr.puts request_string

  # receive reply

  reply_len = @resp_rd.gets.to_i
  reply_string = @resp_rd.read reply_len

  return MultiJson.load reply_string

end

#sessionObject



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/hq/engine/subprocess-rule-provider/self.rb', line 32

def session

  @state == :open \
    or raise "Invalid state #{@state}"

  require "hq/engine/subprocess-rule-provider/session"

  chars = "abcdefghijklmnopqrstuvwxyz"
  session_id = (0...16).map { chars[rand chars.length] }.join("")

  return Session.new self, session_id

end