readapt 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +16 -15
- data/.rspec +2 -2
- data/.travis.yml +18 -18
- data/CHANGELOG.md +72 -69
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +37 -29
- data/Rakefile +14 -14
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/exe/readapt +5 -5
- data/ext/readapt/breakpoints.c +83 -83
- data/ext/readapt/breakpoints.h +11 -11
- data/ext/readapt/extconf.rb +0 -0
- data/ext/readapt/frame.c +137 -137
- data/ext/readapt/frame.h +17 -17
- data/ext/readapt/hash_table.c +211 -211
- data/ext/readapt/hash_table.h +30 -30
- data/ext/readapt/inspector.c +51 -51
- data/ext/readapt/inspector.h +8 -8
- data/ext/readapt/monitor.c +1 -1
- data/ext/readapt/monitor.h +0 -0
- data/ext/readapt/normalize.c +59 -59
- data/ext/readapt/normalize.h +7 -7
- data/ext/readapt/readapt.c +18 -18
- data/ext/readapt/stack.c +86 -86
- data/ext/readapt/stack.h +20 -20
- data/ext/readapt/threads.c +15 -11
- data/ext/readapt/threads.h +1 -1
- data/lib/readapt.rb +21 -20
- data/lib/readapt/adapter.rb +98 -98
- data/lib/readapt/breakpoint.rb +20 -20
- data/lib/readapt/data_reader.rb +62 -62
- data/lib/readapt/debugger.rb +220 -220
- data/lib/readapt/error.rb +63 -63
- data/lib/readapt/finder.rb +20 -20
- data/lib/readapt/frame.rb +40 -40
- data/lib/readapt/input.rb +7 -7
- data/lib/readapt/message.rb +62 -62
- data/lib/readapt/message/attach.rb +11 -11
- data/lib/readapt/message/base.rb +32 -32
- data/lib/readapt/message/configuration_done.rb +11 -11
- data/lib/readapt/message/continue.rb +15 -15
- data/lib/readapt/message/disconnect.rb +13 -13
- data/lib/readapt/message/evaluate.rb +18 -18
- data/lib/readapt/message/initialize.rb +13 -13
- data/lib/readapt/message/launch.rb +11 -11
- data/lib/readapt/message/next.rb +12 -12
- data/lib/readapt/message/pause.rb +11 -11
- data/lib/readapt/message/scopes.rb +26 -26
- data/lib/readapt/message/set_breakpoints.rb +25 -25
- data/lib/readapt/message/set_exception_breakpoints.rb +8 -8
- data/lib/readapt/message/stack_trace.rb +38 -38
- data/lib/readapt/message/step_in.rb +11 -11
- data/lib/readapt/message/step_out.rb +11 -11
- data/lib/readapt/message/threads.rb +18 -18
- data/lib/readapt/message/variables.rb +61 -61
- data/lib/readapt/monitor.rb +0 -0
- data/lib/readapt/output.rb +25 -25
- data/lib/readapt/references.rb +27 -0
- data/lib/readapt/server.rb +22 -22
- data/lib/readapt/shell.rb +104 -104
- data/lib/readapt/snapshot.rb +0 -0
- data/lib/readapt/thread.rb +23 -23
- data/lib/readapt/variable.rb +1 -1
- data/lib/readapt/version.rb +3 -3
- data/readapt.gemspec +39 -39
- metadata +4 -3
data/lib/readapt/debugger.rb
CHANGED
@@ -1,220 +1,220 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'backport'
|
4
|
-
require 'observer'
|
5
|
-
require 'set'
|
6
|
-
|
7
|
-
module Readapt
|
8
|
-
class Debugger
|
9
|
-
include Observable
|
10
|
-
include Finder
|
11
|
-
|
12
|
-
attr_reader :monitor
|
13
|
-
|
14
|
-
attr_reader :file
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@stack = []
|
18
|
-
@frames = {}
|
19
|
-
@running = false
|
20
|
-
@attached = false
|
21
|
-
@request = nil
|
22
|
-
@config = {}
|
23
|
-
@original_argv = ARGV.clone
|
24
|
-
@original_prog = $0
|
25
|
-
@breakpoints = {}
|
26
|
-
end
|
27
|
-
|
28
|
-
def config arguments, request
|
29
|
-
@file = Readapt.normalize_path(find(arguments['program']))
|
30
|
-
@config = arguments
|
31
|
-
@request = request
|
32
|
-
rescue LoadError => e
|
33
|
-
STDERR.puts e.message
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Readapt::Thread]
|
37
|
-
def thread id
|
38
|
-
Thread.find(id)
|
39
|
-
end
|
40
|
-
|
41
|
-
def threads
|
42
|
-
Thread.all
|
43
|
-
end
|
44
|
-
|
45
|
-
def frame id
|
46
|
-
@frames[id] || Frame::NULL_FRAME
|
47
|
-
end
|
48
|
-
|
49
|
-
def launched?
|
50
|
-
@request == :launch
|
51
|
-
end
|
52
|
-
|
53
|
-
def attached?
|
54
|
-
@request == :attach
|
55
|
-
end
|
56
|
-
|
57
|
-
def start
|
58
|
-
::Thread.new do
|
59
|
-
set_program_args
|
60
|
-
run { load @file }
|
61
|
-
set_original_args
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def run
|
66
|
-
# raise RuntimeError, 'Debugger is already running' if @running
|
67
|
-
@running = true
|
68
|
-
send_event('process', {
|
69
|
-
name: @file
|
70
|
-
})
|
71
|
-
Monitor.start @file do |snapshot|
|
72
|
-
debug snapshot
|
73
|
-
end
|
74
|
-
yield if block_given?
|
75
|
-
rescue StandardError => e
|
76
|
-
STDERR.puts "[#{e.class}] #{e.message}"
|
77
|
-
STDERR.puts e.backtrace.join("\n")
|
78
|
-
ensure
|
79
|
-
Monitor.stop
|
80
|
-
@running = false
|
81
|
-
STDOUT.flush #unless STDOUT.closed?
|
82
|
-
STDERR.flush #unless STDERR.closed?
|
83
|
-
changed
|
84
|
-
send_event 'terminated', nil
|
85
|
-
end
|
86
|
-
|
87
|
-
def output data, category = :console
|
88
|
-
send_event('output', {
|
89
|
-
output: data,
|
90
|
-
category: category
|
91
|
-
})
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_breakpoint source, line
|
95
|
-
@breakpoints["#{source}:#{line}"] || Breakpoint.new(source, line, nil, 0)
|
96
|
-
end
|
97
|
-
|
98
|
-
def set_breakpoint source, line, condition, hitcount
|
99
|
-
@breakpoints["#{source}:#{line}"] = Breakpoint.new(source, line, condition, hitcount)
|
100
|
-
end
|
101
|
-
|
102
|
-
def clear_breakpoints source
|
103
|
-
@breakpoints.delete_if { |_key, value|
|
104
|
-
value.source == source
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
def disconnect
|
109
|
-
shutdown if launched?
|
110
|
-
@request = nil
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.run &block
|
114
|
-
new.run &block
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
# @param [Snapshot]
|
120
|
-
# return [void]
|
121
|
-
def debug snapshot
|
122
|
-
sleep 0.001 # @todo Trying to let thread data sync
|
123
|
-
|
124
|
-
|
125
|
-
thr
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
thr
|
134
|
-
|
135
|
-
send_event('thread', {
|
136
|
-
reason: 'exited',
|
137
|
-
threadId: snapshot.thread_id
|
138
|
-
})
|
139
|
-
snapshot.control = :continue
|
140
|
-
else
|
141
|
-
confirmed_pause = true
|
142
|
-
thread = self.thread(snapshot.thread_id)
|
143
|
-
if snapshot.event == :breakpoint
|
144
|
-
bp = get_breakpoint(snapshot.file, snapshot.line)
|
145
|
-
unless bp.condition.nil? || bp.condition.empty?
|
146
|
-
# @type [Binding]
|
147
|
-
bnd = thread.frames.first.frame_binding
|
148
|
-
begin
|
149
|
-
unless bnd.eval(bp.condition)
|
150
|
-
confirmed_pause = false
|
151
|
-
end
|
152
|
-
rescue Exception => e
|
153
|
-
STDERR.puts "Breakpoint condition raised an error"
|
154
|
-
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
155
|
-
STDERR.puts "[#{e.class}] #{e.message}"
|
156
|
-
confirmed_pause = false
|
157
|
-
end
|
158
|
-
end
|
159
|
-
unless !confirmed_pause || bp.hit_condition.nil? || bp.hit_condition.empty?
|
160
|
-
bp.hit_cursor += 1
|
161
|
-
bnd = thread.frames.first.frame_binding
|
162
|
-
begin
|
163
|
-
hit_count = bnd.eval(bp.hit_condition)
|
164
|
-
if bp.hit_cursor == hit_count
|
165
|
-
bp.hit_cursor = 0
|
166
|
-
else
|
167
|
-
confirmed_pause = false
|
168
|
-
end
|
169
|
-
rescue Exception => e
|
170
|
-
STDERR.puts "Breakpoint condition raised an error"
|
171
|
-
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
172
|
-
STDERR.puts "[#{e.class}] #{e.message}"
|
173
|
-
confirmed_pause = false
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
if confirmed_pause
|
178
|
-
changed
|
179
|
-
thread.control = :pause
|
180
|
-
thread.frames.each do |frm|
|
181
|
-
@frames[frm.local_id] = frm
|
182
|
-
end
|
183
|
-
send_event('stopped', {
|
184
|
-
reason: snapshot.event,
|
185
|
-
threadId: thread.id
|
186
|
-
})
|
187
|
-
sleep 0.01 until thread.control != :pause || !Thread.include?(thread.id)
|
188
|
-
thread.frames.each do |frm|
|
189
|
-
@frames.delete frm.local_id
|
190
|
-
end
|
191
|
-
else
|
192
|
-
thread.control = :continue
|
193
|
-
end
|
194
|
-
snapshot.control = thread.control
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def set_program_args
|
199
|
-
$0 = file
|
200
|
-
ARGV.clear
|
201
|
-
ARGV.replace(@config['programArgs'] || [])
|
202
|
-
end
|
203
|
-
|
204
|
-
def set_original_args
|
205
|
-
$0 = @original_prog
|
206
|
-
ARGV.clear
|
207
|
-
ARGV.replace @original_argv
|
208
|
-
end
|
209
|
-
|
210
|
-
def shutdown
|
211
|
-
exit
|
212
|
-
end
|
213
|
-
|
214
|
-
def send_event event, data, wait = false
|
215
|
-
changed
|
216
|
-
notify_observers event, data
|
217
|
-
sleep 0.01 if wait
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'backport'
|
4
|
+
require 'observer'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module Readapt
|
8
|
+
class Debugger
|
9
|
+
include Observable
|
10
|
+
include Finder
|
11
|
+
|
12
|
+
attr_reader :monitor
|
13
|
+
|
14
|
+
attr_reader :file
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@stack = []
|
18
|
+
@frames = {}
|
19
|
+
@running = false
|
20
|
+
@attached = false
|
21
|
+
@request = nil
|
22
|
+
@config = {}
|
23
|
+
@original_argv = ARGV.clone
|
24
|
+
@original_prog = $0
|
25
|
+
@breakpoints = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def config arguments, request
|
29
|
+
@file = Readapt.normalize_path(find(arguments['program']))
|
30
|
+
@config = arguments
|
31
|
+
@request = request
|
32
|
+
rescue LoadError => e
|
33
|
+
STDERR.puts e.message
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Readapt::Thread]
|
37
|
+
def thread id
|
38
|
+
Thread.find(id)
|
39
|
+
end
|
40
|
+
|
41
|
+
def threads
|
42
|
+
Thread.all
|
43
|
+
end
|
44
|
+
|
45
|
+
def frame id
|
46
|
+
@frames[id] || Frame::NULL_FRAME
|
47
|
+
end
|
48
|
+
|
49
|
+
def launched?
|
50
|
+
@request == :launch
|
51
|
+
end
|
52
|
+
|
53
|
+
def attached?
|
54
|
+
@request == :attach
|
55
|
+
end
|
56
|
+
|
57
|
+
def start
|
58
|
+
::Thread.new do
|
59
|
+
set_program_args
|
60
|
+
run { load @file }
|
61
|
+
set_original_args
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def run
|
66
|
+
# raise RuntimeError, 'Debugger is already running' if @running
|
67
|
+
@running = true
|
68
|
+
send_event('process', {
|
69
|
+
name: @file
|
70
|
+
})
|
71
|
+
Monitor.start @file do |snapshot|
|
72
|
+
debug snapshot
|
73
|
+
end
|
74
|
+
yield if block_given?
|
75
|
+
rescue StandardError => e
|
76
|
+
STDERR.puts "[#{e.class}] #{e.message}"
|
77
|
+
STDERR.puts e.backtrace.join("\n")
|
78
|
+
ensure
|
79
|
+
Monitor.stop
|
80
|
+
@running = false
|
81
|
+
STDOUT.flush #unless STDOUT.closed?
|
82
|
+
STDERR.flush #unless STDERR.closed?
|
83
|
+
changed
|
84
|
+
send_event 'terminated', nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def output data, category = :console
|
88
|
+
send_event('output', {
|
89
|
+
output: data,
|
90
|
+
category: category
|
91
|
+
})
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_breakpoint source, line
|
95
|
+
@breakpoints["#{source}:#{line}"] || Breakpoint.new(source, line, nil, 0)
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_breakpoint source, line, condition, hitcount
|
99
|
+
@breakpoints["#{source}:#{line}"] = Breakpoint.new(source, line, condition, hitcount)
|
100
|
+
end
|
101
|
+
|
102
|
+
def clear_breakpoints source
|
103
|
+
@breakpoints.delete_if { |_key, value|
|
104
|
+
value.source == source
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def disconnect
|
109
|
+
shutdown if launched?
|
110
|
+
@request = nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.run &block
|
114
|
+
new.run &block
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# @param [Snapshot]
|
120
|
+
# return [void]
|
121
|
+
def debug snapshot
|
122
|
+
sleep 0.001 # @todo Trying to let thread data sync
|
123
|
+
References.clear
|
124
|
+
if snapshot.event == :thread_begin || snapshot.event == :entry
|
125
|
+
thr = Thread.find(snapshot.thread_id)
|
126
|
+
thr.control = :continue
|
127
|
+
send_event('thread', {
|
128
|
+
reason: 'started',
|
129
|
+
threadId: snapshot.thread_id
|
130
|
+
}, true)
|
131
|
+
snapshot.control = :continue
|
132
|
+
elsif snapshot.event == :thread_end
|
133
|
+
thr = thread(snapshot.thread_id)
|
134
|
+
thr.control = :continue
|
135
|
+
send_event('thread', {
|
136
|
+
reason: 'exited',
|
137
|
+
threadId: snapshot.thread_id
|
138
|
+
})
|
139
|
+
snapshot.control = :continue
|
140
|
+
else
|
141
|
+
confirmed_pause = true
|
142
|
+
thread = self.thread(snapshot.thread_id)
|
143
|
+
if snapshot.event == :breakpoint
|
144
|
+
bp = get_breakpoint(snapshot.file, snapshot.line)
|
145
|
+
unless bp.condition.nil? || bp.condition.empty?
|
146
|
+
# @type [Binding]
|
147
|
+
bnd = thread.frames.first.frame_binding
|
148
|
+
begin
|
149
|
+
unless bnd.eval(bp.condition)
|
150
|
+
confirmed_pause = false
|
151
|
+
end
|
152
|
+
rescue Exception => e
|
153
|
+
STDERR.puts "Breakpoint condition raised an error"
|
154
|
+
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
155
|
+
STDERR.puts "[#{e.class}] #{e.message}"
|
156
|
+
confirmed_pause = false
|
157
|
+
end
|
158
|
+
end
|
159
|
+
unless !confirmed_pause || bp.hit_condition.nil? || bp.hit_condition.empty?
|
160
|
+
bp.hit_cursor += 1
|
161
|
+
bnd = thread.frames.first.frame_binding
|
162
|
+
begin
|
163
|
+
hit_count = bnd.eval(bp.hit_condition)
|
164
|
+
if bp.hit_cursor == hit_count
|
165
|
+
bp.hit_cursor = 0
|
166
|
+
else
|
167
|
+
confirmed_pause = false
|
168
|
+
end
|
169
|
+
rescue Exception => e
|
170
|
+
STDERR.puts "Breakpoint condition raised an error"
|
171
|
+
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
172
|
+
STDERR.puts "[#{e.class}] #{e.message}"
|
173
|
+
confirmed_pause = false
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
if confirmed_pause
|
178
|
+
changed
|
179
|
+
thread.control = :pause
|
180
|
+
thread.frames.each do |frm|
|
181
|
+
@frames[frm.local_id] = frm
|
182
|
+
end
|
183
|
+
send_event('stopped', {
|
184
|
+
reason: snapshot.event,
|
185
|
+
threadId: thread.id
|
186
|
+
})
|
187
|
+
sleep 0.01 until thread.control != :pause || !Thread.include?(thread.id)
|
188
|
+
thread.frames.each do |frm|
|
189
|
+
@frames.delete frm.local_id
|
190
|
+
end
|
191
|
+
else
|
192
|
+
thread.control = :continue
|
193
|
+
end
|
194
|
+
snapshot.control = thread.control
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def set_program_args
|
199
|
+
$0 = file
|
200
|
+
ARGV.clear
|
201
|
+
ARGV.replace(@config['programArgs'] || [])
|
202
|
+
end
|
203
|
+
|
204
|
+
def set_original_args
|
205
|
+
$0 = @original_prog
|
206
|
+
ARGV.clear
|
207
|
+
ARGV.replace @original_argv
|
208
|
+
end
|
209
|
+
|
210
|
+
def shutdown
|
211
|
+
exit
|
212
|
+
end
|
213
|
+
|
214
|
+
def send_event event, data, wait = false
|
215
|
+
changed
|
216
|
+
notify_observers event, data
|
217
|
+
sleep 0.01 if wait
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
data/lib/readapt/error.rb
CHANGED
@@ -1,63 +1,63 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
module Error
|
5
|
-
class << self
|
6
|
-
attr_accessor :adapter
|
7
|
-
end
|
8
|
-
|
9
|
-
def opening
|
10
|
-
@buffer = ''
|
11
|
-
end
|
12
|
-
|
13
|
-
def receiving data
|
14
|
-
output = ''
|
15
|
-
data.each_char do |char|
|
16
|
-
@buffer += char
|
17
|
-
if open_message.start_with?(@buffer) || @buffer.start_with?(open_message)
|
18
|
-
if @buffer.end_with?(close_message)
|
19
|
-
msg = @buffer[open_message.length..-(close_message.length+1)]
|
20
|
-
exit if msg == '__TERMINATE__'
|
21
|
-
Error.adapter.write msg
|
22
|
-
@buffer.clear
|
23
|
-
end
|
24
|
-
else
|
25
|
-
output += @buffer
|
26
|
-
@buffer.clear
|
27
|
-
end
|
28
|
-
end
|
29
|
-
return if output.empty?
|
30
|
-
send_event('output', {
|
31
|
-
output: output,
|
32
|
-
category: 'stderr'
|
33
|
-
})
|
34
|
-
end
|
35
|
-
|
36
|
-
def send_event event, data
|
37
|
-
obj = {
|
38
|
-
type: 'event',
|
39
|
-
event: event
|
40
|
-
}
|
41
|
-
obj[:body] = data unless data.nil?
|
42
|
-
json = obj.to_json
|
43
|
-
envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
|
44
|
-
Error.adapter.write envelope
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.procid= pid
|
48
|
-
@@procid = pid
|
49
|
-
end
|
50
|
-
|
51
|
-
def procid
|
52
|
-
@@procid
|
53
|
-
end
|
54
|
-
|
55
|
-
def open_message
|
56
|
-
@@open_message ||= "<readapt-#{procid}>"
|
57
|
-
end
|
58
|
-
|
59
|
-
def close_message
|
60
|
-
@@close_message ||= "</readapt-#{procid}>"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
module Error
|
5
|
+
class << self
|
6
|
+
attr_accessor :adapter
|
7
|
+
end
|
8
|
+
|
9
|
+
def opening
|
10
|
+
@buffer = ''
|
11
|
+
end
|
12
|
+
|
13
|
+
def receiving data
|
14
|
+
output = ''
|
15
|
+
data.each_char do |char|
|
16
|
+
@buffer += char
|
17
|
+
if open_message.start_with?(@buffer) || @buffer.start_with?(open_message)
|
18
|
+
if @buffer.end_with?(close_message)
|
19
|
+
msg = @buffer[open_message.length..-(close_message.length+1)]
|
20
|
+
exit if msg == '__TERMINATE__'
|
21
|
+
Error.adapter.write msg
|
22
|
+
@buffer.clear
|
23
|
+
end
|
24
|
+
else
|
25
|
+
output += @buffer
|
26
|
+
@buffer.clear
|
27
|
+
end
|
28
|
+
end
|
29
|
+
return if output.empty?
|
30
|
+
send_event('output', {
|
31
|
+
output: output,
|
32
|
+
category: 'stderr'
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_event event, data
|
37
|
+
obj = {
|
38
|
+
type: 'event',
|
39
|
+
event: event
|
40
|
+
}
|
41
|
+
obj[:body] = data unless data.nil?
|
42
|
+
json = obj.to_json
|
43
|
+
envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
|
44
|
+
Error.adapter.write envelope
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.procid= pid
|
48
|
+
@@procid = pid
|
49
|
+
end
|
50
|
+
|
51
|
+
def procid
|
52
|
+
@@procid
|
53
|
+
end
|
54
|
+
|
55
|
+
def open_message
|
56
|
+
@@open_message ||= "<readapt-#{procid}>"
|
57
|
+
end
|
58
|
+
|
59
|
+
def close_message
|
60
|
+
@@close_message ||= "</readapt-#{procid}>"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|