union_station_hooks_core 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE.md +19 -0
- data/README.md +117 -0
- data/lib/union_station_hooks_core.rb +360 -0
- data/lib/union_station_hooks_core/api.rb +182 -0
- data/lib/union_station_hooks_core/connection.rb +67 -0
- data/lib/union_station_hooks_core/context.rb +297 -0
- data/lib/union_station_hooks_core/lock.rb +62 -0
- data/lib/union_station_hooks_core/log.rb +66 -0
- data/lib/union_station_hooks_core/message_channel.rb +157 -0
- data/lib/union_station_hooks_core/request_reporter.rb +141 -0
- data/lib/union_station_hooks_core/request_reporter/basics.rb +132 -0
- data/lib/union_station_hooks_core/request_reporter/controllers.rb +187 -0
- data/lib/union_station_hooks_core/request_reporter/misc.rb +218 -0
- data/lib/union_station_hooks_core/request_reporter/view_rendering.rb +76 -0
- data/lib/union_station_hooks_core/spec_helper.rb +241 -0
- data/lib/union_station_hooks_core/time_point.rb +53 -0
- data/lib/union_station_hooks_core/transaction.rb +182 -0
- data/lib/union_station_hooks_core/utils.rb +161 -0
- data/lib/union_station_hooks_core/version.rb +32 -0
- data/lib/union_station_hooks_core/version_data.rb +44 -0
- metadata +64 -0
@@ -0,0 +1,241 @@
|
|
1
|
+
# Union Station - https://www.unionstationapp.com/
|
2
|
+
# Copyright (c) 2010-2015 Phusion Holding B.V.
|
3
|
+
#
|
4
|
+
# "Union Station" and "Passenger" are trademarks of Phusion Holding B.V.
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
|
24
|
+
require 'fileutils'
|
25
|
+
require 'net/http'
|
26
|
+
require 'uri'
|
27
|
+
|
28
|
+
module UnionStationHooks
|
29
|
+
# Contains helper methods for use in unit tests across all the
|
30
|
+
# `union_station_hooks_*` gems.
|
31
|
+
#
|
32
|
+
# @private
|
33
|
+
module SpecHelper
|
34
|
+
extend self # Make methods available as class methods.
|
35
|
+
|
36
|
+
def self.included(klass)
|
37
|
+
# When included into another class, make sure that Utils
|
38
|
+
# methods are made private.
|
39
|
+
public_instance_methods(false).each do |method_name|
|
40
|
+
klass.send(:private, method_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# To be called during initialization of the test suite.
|
45
|
+
def initialize!
|
46
|
+
load_passenger
|
47
|
+
initialize_ush_api
|
48
|
+
initialize_debugging
|
49
|
+
undo_bundler
|
50
|
+
end
|
51
|
+
|
52
|
+
# Lookup the `passenger-config` command, either by respecting the
|
53
|
+
# `PASSENGER_CONFIG` environment variable, or by looking it up in `PATH`.
|
54
|
+
# If the command cannot be found, the current process aborts with an
|
55
|
+
# error message.
|
56
|
+
def find_passenger_config
|
57
|
+
passenger_config = ENV['PASSENGER_CONFIG']
|
58
|
+
if passenger_config.nil? || passenger_config.empty?
|
59
|
+
ENV['PATH'].split(':').each do |path|
|
60
|
+
if File.exist?("#{path}/passenger-config")
|
61
|
+
passenger_config = "#{path}/passenger-config"
|
62
|
+
break
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
if passenger_config.nil? || passenger_config.empty?
|
67
|
+
abort 'ERROR: The unit tests are to be run against a specific ' \
|
68
|
+
'Passenger version. However, the \'passenger-config\' command is ' \
|
69
|
+
'not found. Please install Passenger, or (if you are sure ' \
|
70
|
+
'Passenger is installed) set the PASSENGER_CONFIG environment ' \
|
71
|
+
'variable to the \'passenger-config\' command.'
|
72
|
+
end
|
73
|
+
passenger_config
|
74
|
+
end
|
75
|
+
|
76
|
+
# Uses `find_passenger_config` to lookup a Passenger installation, and
|
77
|
+
# loads the Passenger Ruby support library associated with that
|
78
|
+
# installation. All the constants defined in the Passenger Ruby support
|
79
|
+
# library are loaded. In addition, checks whether the Passenger agent
|
80
|
+
# executable is installed. If not, the current process aborts with an
|
81
|
+
# error message.
|
82
|
+
def load_passenger
|
83
|
+
passenger_config = find_passenger_config
|
84
|
+
puts "Using Passenger installation at: #{passenger_config}"
|
85
|
+
passenger_ruby_libdir = `#{passenger_config} about ruby-libdir`.strip
|
86
|
+
require("#{passenger_ruby_libdir}/phusion_passenger")
|
87
|
+
PhusionPassenger.locate_directories
|
88
|
+
PhusionPassenger.require_passenger_lib 'constants'
|
89
|
+
puts "Loaded Passenger version #{PhusionPassenger::VERSION_STRING}"
|
90
|
+
|
91
|
+
agent = PhusionPassenger.find_support_binary(PhusionPassenger::AGENT_EXE)
|
92
|
+
if agent.nil?
|
93
|
+
abort "ERROR: The Passenger agent isn't installed. Please ensure " \
|
94
|
+
"that it is installed, e.g. using:\n\n" \
|
95
|
+
" #{passenger_config} install-agent\n\n"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def initialize_ush_api
|
100
|
+
UnionStationHooks.require_lib('api')
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize_debugging
|
104
|
+
@@debug = !ENV['DEBUG'].to_s.empty?
|
105
|
+
if @@debug
|
106
|
+
UnionStationHooks.require_lib('log')
|
107
|
+
UnionStationHooks::Log.debugging = true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Unit tests must undo the Bundler environment so that the gem's
|
112
|
+
# own Gemfile doesn't affect subprocesses that may have their
|
113
|
+
# own Gemfile.
|
114
|
+
def undo_bundler
|
115
|
+
clean_env = nil
|
116
|
+
Bundler.with_clean_env do
|
117
|
+
clean_env = ENV.to_hash
|
118
|
+
end
|
119
|
+
ENV.replace(clean_env)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Checks whether `initialize_debugging` enabled debugging mode.
|
123
|
+
def debug?
|
124
|
+
@@debug
|
125
|
+
end
|
126
|
+
|
127
|
+
# Writes the given content to the file at the given path. If or or more
|
128
|
+
# parent directories don't exist, then they are created.
|
129
|
+
def write_file(path, content)
|
130
|
+
dir = File.dirname(path)
|
131
|
+
if !File.exist?(dir)
|
132
|
+
FileUtils.mkdir_p(dir)
|
133
|
+
end
|
134
|
+
File.open(path, 'wb') do |f|
|
135
|
+
f.write(content)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_response(path)
|
140
|
+
uri = URI.parse("#{root_url}#{path}")
|
141
|
+
Net::HTTP.get_response(uri)
|
142
|
+
end
|
143
|
+
|
144
|
+
def get(path)
|
145
|
+
response = get_response(path)
|
146
|
+
return_200_response_body(path, response)
|
147
|
+
end
|
148
|
+
|
149
|
+
def return_200_response_body(path, response)
|
150
|
+
if response.code == '200'
|
151
|
+
response.body
|
152
|
+
else
|
153
|
+
raise "HTTP request to #{path} failed.\n" \
|
154
|
+
"Code: #{response.code}\n" \
|
155
|
+
"Body:\n" \
|
156
|
+
"#{response.body}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Opens a debug shell. By default, the debug shell is opened in the current
|
161
|
+
# working directory. If the current module has the `prepare_debug_shell`
|
162
|
+
# method, that method is called before opening the debug shell. The method
|
163
|
+
# could, for example, change the working directory.
|
164
|
+
#
|
165
|
+
# This method does *not* raise an exception if the debug shell exits with
|
166
|
+
# an error.
|
167
|
+
def debug_shell
|
168
|
+
puts '------ Opening debug shell -----'
|
169
|
+
@orig_dir = Dir.pwd
|
170
|
+
begin
|
171
|
+
if respond_to?(:prepare_debug_shell)
|
172
|
+
prepare_debug_shell
|
173
|
+
end
|
174
|
+
system('bash')
|
175
|
+
ensure
|
176
|
+
Dir.chdir(@orig_dir)
|
177
|
+
end
|
178
|
+
puts '------ Exiting debug shell -----'
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns the path of a specific UstRouter dump file.
|
182
|
+
# Requires that `@dump_dir` is set.
|
183
|
+
def dump_file_path(category = 'requests')
|
184
|
+
raise '@dump_dir variable required' if !@dump_dir
|
185
|
+
"#{@dump_dir}/#{category}"
|
186
|
+
end
|
187
|
+
|
188
|
+
# Reads the contents of a specific UstRouter dump file.
|
189
|
+
# Requires that `@dump_dir` is set.
|
190
|
+
#
|
191
|
+
# @raise SystemError Something went wrong during reading.
|
192
|
+
def read_dump_file(category = 'requests')
|
193
|
+
File.read(dump_file_path(category))
|
194
|
+
end
|
195
|
+
|
196
|
+
# Waits until the dump file exists. Raises an error if
|
197
|
+
# this doesn't become true within the default {#eventually}
|
198
|
+
# timeout.
|
199
|
+
def wait_for_dump_file_existance(category = 'requests')
|
200
|
+
eventually do
|
201
|
+
File.exist?(dump_file_path(category))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Makes `UnionStationHooks::Log.warn` not print anything.
|
206
|
+
def silence_warnings
|
207
|
+
UnionStationHooks::Log.warn_callback = lambda { |_message| }
|
208
|
+
end
|
209
|
+
|
210
|
+
# Asserts that something should eventually happen. This is done by checking
|
211
|
+
# that the given block eventually returns true. The block is called
|
212
|
+
# once every `check_interval` msec. If the block does not return true
|
213
|
+
# within `deadline_duration` secs, then an exception is raised.
|
214
|
+
def eventually(deadline_duration = 3, check_interval = 0.05)
|
215
|
+
deadline = Time.now + deadline_duration
|
216
|
+
while Time.now < deadline
|
217
|
+
if yield
|
218
|
+
return
|
219
|
+
else
|
220
|
+
sleep(check_interval)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
raise 'Time limit exceeded'
|
224
|
+
end
|
225
|
+
|
226
|
+
# Asserts that something should never happen. This is done by checking that
|
227
|
+
# the given block never returns true. The block is called once every
|
228
|
+
# `check_interval` msec, until `deadline_duration` seconds have passed.
|
229
|
+
# If the block ever returns true, then an exception is raised.
|
230
|
+
def should_never_happen(deadline_duration = 0.5, check_interval = 0.05)
|
231
|
+
deadline = Time.now + deadline_duration
|
232
|
+
while Time.now < deadline
|
233
|
+
if yield
|
234
|
+
raise "That which shouldn't happen happened anyway"
|
235
|
+
else
|
236
|
+
sleep(check_interval)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Union Station - https://www.unionstationapp.com/
|
2
|
+
# Copyright (c) 2010-2015 Phusion Holding B.V.
|
3
|
+
#
|
4
|
+
# "Union Station" and "Passenger" are trademarks of Phusion Holding B.V.
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
|
24
|
+
|
25
|
+
module UnionStationHooks
|
26
|
+
# See {UnionStationHooks.now} for more information.
|
27
|
+
class TimePoint
|
28
|
+
# @api private
|
29
|
+
attr_reader :time, :utime, :stime
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def initialize(time, utime, stime)
|
33
|
+
@time = time
|
34
|
+
@utime = utime
|
35
|
+
@stime = stime
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def usec_timestamp
|
40
|
+
@time.to_i * 1_000_000 + @time.usec
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
def usec
|
45
|
+
@time.usec
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def to_i
|
50
|
+
@time.to_i
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# Union Station - https://www.unionstationapp.com/
|
2
|
+
# Copyright (c) 2010-2015 Phusion Holding B.V.
|
3
|
+
#
|
4
|
+
# "Union Station" and "Passenger" are trademarks of Phusion Holding B.V.
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
|
24
|
+
UnionStationHooks.require_lib 'log'
|
25
|
+
UnionStationHooks.require_lib 'context'
|
26
|
+
UnionStationHooks.require_lib 'time_point'
|
27
|
+
UnionStationHooks.require_lib 'utils'
|
28
|
+
|
29
|
+
module UnionStationHooks
|
30
|
+
# @private
|
31
|
+
class Transaction
|
32
|
+
attr_reader :txn_id
|
33
|
+
|
34
|
+
def initialize(connection, txn_id)
|
35
|
+
@connection = connection
|
36
|
+
@txn_id = txn_id
|
37
|
+
if connection
|
38
|
+
raise ArgumentError, 'Transaction ID required' if txn_id.nil?
|
39
|
+
connection.ref
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def null?
|
44
|
+
!@connection || !@connection.connected?
|
45
|
+
end
|
46
|
+
|
47
|
+
def message(text)
|
48
|
+
if !@connection
|
49
|
+
log_message_to_null(text)
|
50
|
+
return
|
51
|
+
end
|
52
|
+
|
53
|
+
@connection.synchronize do
|
54
|
+
if !@connection.connected?
|
55
|
+
log_message_to_null(text)
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
UnionStationHooks::Log.debug('[Union Station log] ' \
|
60
|
+
"#{@txn_id} #{Utils.encoded_timestamp} #{text}")
|
61
|
+
|
62
|
+
io_operation do
|
63
|
+
@connection.channel.write('log', @txn_id, Utils.encoded_timestamp)
|
64
|
+
@connection.channel.write_scalar(text)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def log_activity_block(name, extra_info = nil)
|
70
|
+
has_error = false
|
71
|
+
log_activity_begin(name, UnionStationHooks.now, extra_info)
|
72
|
+
begin
|
73
|
+
yield
|
74
|
+
rescue Exception
|
75
|
+
has_error = true
|
76
|
+
is_closed = closed?
|
77
|
+
raise
|
78
|
+
ensure
|
79
|
+
if !is_closed
|
80
|
+
log_activity_end(name, UnionStationHooks.now, has_error)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def log_activity_begin(name, time = UnionStationHooks.now, extra_info = nil)
|
86
|
+
if extra_info
|
87
|
+
extra_info_base64 = Utils.base64(extra_info)
|
88
|
+
else
|
89
|
+
extra_info_base64 = nil
|
90
|
+
end
|
91
|
+
if time.is_a?(TimePoint)
|
92
|
+
message "BEGIN: #{name} (#{Utils.encoded_timestamp(time)}," \
|
93
|
+
"#{time.utime.to_s(36)},#{time.stime.to_s(36)}) " \
|
94
|
+
"#{extra_info_base64}"
|
95
|
+
else
|
96
|
+
message "BEGIN: #{name} (#{Utils.encoded_timestamp(time)})" \
|
97
|
+
" #{extra_info_base64}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def log_activity_end(name, time = UnionStationHooks.now, has_error = false)
|
102
|
+
if time.is_a?(TimePoint)
|
103
|
+
if has_error
|
104
|
+
message "FAIL: #{name} (#{Utils.encoded_timestamp(time)}," \
|
105
|
+
"#{time.utime.to_s(36)},#{time.stime.to_s(36)})"
|
106
|
+
else
|
107
|
+
message "END: #{name} (#{Utils.encoded_timestamp(time)}," \
|
108
|
+
"#{time.utime.to_s(36)},#{time.stime.to_s(36)})"
|
109
|
+
end
|
110
|
+
else
|
111
|
+
if has_error
|
112
|
+
message "FAIL: #{name} (#{Utils.encoded_timestamp(time)})"
|
113
|
+
else
|
114
|
+
message "END: #{name} (#{Utils.encoded_timestamp(time)})"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def log_activity(name, begin_time, end_time, extra_info = nil,
|
120
|
+
has_error = false)
|
121
|
+
log_activity_begin(name, begin_time, extra_info)
|
122
|
+
log_activity_end(name, end_time, has_error)
|
123
|
+
end
|
124
|
+
|
125
|
+
def close(should_flush_to_disk = false)
|
126
|
+
return if !@connection
|
127
|
+
|
128
|
+
@connection.synchronize do
|
129
|
+
return if !@connection.connected?
|
130
|
+
|
131
|
+
begin
|
132
|
+
io_operation do
|
133
|
+
# We need an ACK here so that we the UstRouter doesn't end up
|
134
|
+
# processing the Core's openTransaction and closeTransaction pair
|
135
|
+
# before it has received this process's openTransaction command.
|
136
|
+
@connection.channel.write('closeTransaction', @txn_id,
|
137
|
+
Utils.encoded_timestamp, true)
|
138
|
+
Utils.process_ust_router_reply(@connection.channel,
|
139
|
+
"Error handling reply for 'closeTransaction' message")
|
140
|
+
if should_flush_to_disk
|
141
|
+
flush_to_disk
|
142
|
+
end
|
143
|
+
end
|
144
|
+
ensure
|
145
|
+
@connection.unref
|
146
|
+
@connection = nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def closed?
|
152
|
+
return nil if !@connection
|
153
|
+
@connection.synchronize do
|
154
|
+
!@connection.connected?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def log_message_to_null(text)
|
161
|
+
UnionStationHooks::Log.debug('[Union Station log to null] ' \
|
162
|
+
"#{@txn_id} #{Utils.encoded_timestamp} #{text}")
|
163
|
+
end
|
164
|
+
|
165
|
+
def io_operation
|
166
|
+
yield
|
167
|
+
rescue SystemCallError, IOError => e
|
168
|
+
@connection.disconnect
|
169
|
+
UnionStationHooks::Log.warn(
|
170
|
+
"Error communicating with the UstRouter: #{e.message}")
|
171
|
+
rescue Exception => e
|
172
|
+
@connection.disconnect
|
173
|
+
raise e
|
174
|
+
end
|
175
|
+
|
176
|
+
def flush_to_disk
|
177
|
+
@connection.channel.write('flush')
|
178
|
+
Utils.process_ust_router_reply(@connection.channel,
|
179
|
+
"Error handling reply for 'flush' message")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|