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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(req_wr, resp_rd) ⇒ SubProcessRuleProvider

Returns a new instance of SubProcessRuleProvider.



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

def initialize req_wr, resp_rd

	@state = :error

	@req_wr = req_wr
	@resp_rd = resp_rd

	@state = :open

end

Instance Attribute Details

#extensionsObject

Returns the value of attribute extensions.



7
8
9
# File 'lib/hq/engine/subprocess-rule-provider/self.rb', line 7

def extensions
  @extensions
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



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

def close

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

	@state = :error

	@req_wr.close
	@resp_rd.close

	@state = :closed

end

#perform(request) ⇒ Object



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

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



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

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