em-pg-client-12 0.3.4
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 +7 -0
- data/.rspec +1 -0
- data/.travis.yml +32 -0
- data/.yardopts +1 -0
- data/BENCHMARKS.md +91 -0
- data/Gemfile +5 -0
- data/HISTORY.md +107 -0
- data/LICENSE +21 -0
- data/README.md +456 -0
- data/Rakefile +157 -0
- data/benchmarks/em_pg.rb +96 -0
- data/benchmarks/single_row_mode.rb +88 -0
- data/em-pg-client.gemspec +34 -0
- data/examples/single_row_mode.rb +57 -0
- data/lib/em-pg-client.rb +1 -0
- data/lib/em-synchrony/pg.rb +3 -0
- data/lib/pg/em-version.rb +5 -0
- data/lib/pg/em.rb +1129 -0
- data/lib/pg/em/client/connect_watcher.rb +89 -0
- data/lib/pg/em/client/watcher.rb +204 -0
- data/lib/pg/em/connection_pool.rb +480 -0
- data/lib/pg/em/featured_deferrable.rb +43 -0
- data/spec/connection_pool_helpers.rb +89 -0
- data/spec/em_client.rb +33 -0
- data/spec/em_client_autoreconnect.rb +672 -0
- data/spec/em_client_common.rb +619 -0
- data/spec/em_client_on_connect.rb +171 -0
- data/spec/em_connection_pool.rb +200 -0
- data/spec/em_synchrony_client.rb +787 -0
- data/spec/em_synchrony_client_autoreconnect.rb +560 -0
- data/spec/pg_em_client_connect_finish.rb +54 -0
- data/spec/pg_em_client_connect_timeout.rb +91 -0
- data/spec/pg_em_client_options.rb +133 -0
- data/spec/pg_em_connection_pool.rb +679 -0
- data/spec/pg_em_featured_deferrable.rb +125 -0
- data/spec/spec_helper.rb +9 -0
- metadata +187 -0
@@ -0,0 +1,560 @@
|
|
1
|
+
$:.unshift "lib"
|
2
|
+
gem 'eventmachine', '~> 1.0.0'
|
3
|
+
gem 'pg', ENV['EM_PG_CLIENT_TEST_PG_VERSION']
|
4
|
+
require 'date'
|
5
|
+
require 'em-synchrony'
|
6
|
+
require 'pg/em'
|
7
|
+
|
8
|
+
$pgserver_cmd_stop = ENV['PG_CTL_STOP_CMD'] || %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" stop -s -m fast]
|
9
|
+
$pgserver_cmd_start = ENV['PG_CTL_START_CMD'] || %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" start -s -w]
|
10
|
+
|
11
|
+
DISCONNECTED_ERROR = ENV['PGHOST'].include?('/') ? PG::UnableToSend : PG::ConnectionBad
|
12
|
+
|
13
|
+
shared_context 'em-synchrony-pg common' do
|
14
|
+
around(:each) do |testcase|
|
15
|
+
EM.synchrony do
|
16
|
+
testcase.call
|
17
|
+
EM.stop
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:all) do
|
22
|
+
@client.close
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'em-synchrony-pg default autoreconnect' do
|
27
|
+
include_context 'em-synchrony-pg common'
|
28
|
+
|
29
|
+
it "should not have modified argument Hash" do
|
30
|
+
@options.should eq(async_autoreconnect: true)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should get database size using query" do
|
34
|
+
@tested_proc.call
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should get database size using query after server restart" do
|
38
|
+
system($pgserver_cmd_stop).should be_true
|
39
|
+
system($pgserver_cmd_start).should be_true
|
40
|
+
@tested_proc.call
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not get database size using query after server shutdown" do
|
44
|
+
system($pgserver_cmd_stop).should be_true
|
45
|
+
expect {
|
46
|
+
@tested_proc.call
|
47
|
+
}.to raise_error DISCONNECTED_ERROR
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should get database size using query after server startup" do
|
51
|
+
system($pgserver_cmd_start).should be_true
|
52
|
+
@tested_proc.call
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should raise an error when in transaction after server restart" do
|
56
|
+
expect do
|
57
|
+
@client.transaction do
|
58
|
+
system($pgserver_cmd_stop).should be_true
|
59
|
+
system($pgserver_cmd_start).should be_true
|
60
|
+
@tested_proc.call
|
61
|
+
end
|
62
|
+
end.to raise_error DISCONNECTED_ERROR
|
63
|
+
@tested_proc.call
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should fail to get last result asynchronously after server restart" do
|
67
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
68
|
+
system($pgserver_cmd_stop).should be_true
|
69
|
+
system($pgserver_cmd_start).should be_true
|
70
|
+
expect do
|
71
|
+
@client.get_last_result
|
72
|
+
end.to raise_error PG::ConnectionBad
|
73
|
+
@client.status.should be PG::CONNECTION_OK
|
74
|
+
@client.get_last_result.should be_nil
|
75
|
+
EM.stop
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should fail to get each result asynchronously after server restart" do
|
79
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
80
|
+
system($pgserver_cmd_stop).should be_true
|
81
|
+
system($pgserver_cmd_start).should be_true
|
82
|
+
result = @client.get_result
|
83
|
+
result.should be_an_instance_of PG::Result
|
84
|
+
expect do
|
85
|
+
result.check
|
86
|
+
end.to raise_error PG::Error
|
87
|
+
@client.status.should be PG::CONNECTION_OK
|
88
|
+
expect do
|
89
|
+
@client.get_result
|
90
|
+
end.to raise_error PG::ConnectionBad
|
91
|
+
@client.status.should be PG::CONNECTION_OK
|
92
|
+
@client.get_result.should be_nil
|
93
|
+
EM.stop
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should fail wait_for_notify while server restarts" do
|
97
|
+
@client.status.should be PG::CONNECTION_OK
|
98
|
+
f = Fiber.current
|
99
|
+
notify_flag = false
|
100
|
+
Fiber.new do
|
101
|
+
expect {
|
102
|
+
@client.wait_for_notify do
|
103
|
+
raise "This block should not be called"
|
104
|
+
end
|
105
|
+
}.to raise_error(PG::ConnectionBad)
|
106
|
+
@client.status.should be PG::CONNECTION_OK
|
107
|
+
Fiber.new do
|
108
|
+
@client.wait_for_notify do |name,|
|
109
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
110
|
+
notify_flag = true
|
111
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
112
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
113
|
+
f.resume
|
114
|
+
end.resume
|
115
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
116
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
117
|
+
end.resume
|
118
|
+
system($pgserver_cmd_stop).should be_true
|
119
|
+
system($pgserver_cmd_start).should be_true
|
120
|
+
Fiber.yield
|
121
|
+
notify_flag.should be_true
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should fail wait_for_notify and finish slow query while server restarts" do
|
125
|
+
@client.status.should be PG::CONNECTION_OK
|
126
|
+
f = Fiber.current
|
127
|
+
notify_flag = false
|
128
|
+
query_flag = false
|
129
|
+
start_time = Time.now
|
130
|
+
Fiber.new do
|
131
|
+
result = @client.query('SELECT pg_sleep(2); SELECT 42')
|
132
|
+
result.should be_an_instance_of PG::Result
|
133
|
+
result.getvalue(0,0).to_i.should eq 42
|
134
|
+
(Time.now - start_time).should be > 2
|
135
|
+
query_flag = true
|
136
|
+
end.resume
|
137
|
+
Fiber.new do
|
138
|
+
expect {
|
139
|
+
@client.wait_for_notify do
|
140
|
+
raise "This block should not be called"
|
141
|
+
end
|
142
|
+
}.to raise_error(PG::ConnectionBad)
|
143
|
+
query_flag.should be_true
|
144
|
+
@client.status.should be PG::CONNECTION_OK
|
145
|
+
Fiber.new do
|
146
|
+
@client.wait_for_notify do |name,|
|
147
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
148
|
+
notify_flag = true
|
149
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
150
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
151
|
+
f.resume
|
152
|
+
end.resume
|
153
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
154
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
155
|
+
end.resume
|
156
|
+
system($pgserver_cmd_stop).should be_true
|
157
|
+
system($pgserver_cmd_start).should be_true
|
158
|
+
Fiber.yield
|
159
|
+
notify_flag.should be_true
|
160
|
+
end
|
161
|
+
|
162
|
+
before(:all) do
|
163
|
+
@tested_proc = proc do
|
164
|
+
@client.query('SELECT pg_database_size(current_database());') do |result|
|
165
|
+
result.should be_an_instance_of PG::Result
|
166
|
+
result[0]['pg_database_size'].to_i.should be > 0
|
167
|
+
end
|
168
|
+
end
|
169
|
+
@options = {async_autoreconnect: true}
|
170
|
+
@client = PG::EM::Client.new(@options)
|
171
|
+
@client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe 'em-synchrony-pg autoreconnect with on_autoreconnect' do
|
176
|
+
include_context 'em-synchrony-pg common'
|
177
|
+
|
178
|
+
it "should not have modified argument Hash" do
|
179
|
+
@options.should eq(on_autoreconnect: @on_autoreconnect)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should get database size using prepared statement" do
|
183
|
+
@tested_proc.call
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should get database size using prepared statement after server restart" do
|
187
|
+
system($pgserver_cmd_stop).should be_true
|
188
|
+
system($pgserver_cmd_start).should be_true
|
189
|
+
@tested_proc.call
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should raise an error when in transaction after server restart" do
|
193
|
+
expect do
|
194
|
+
@client.transaction do
|
195
|
+
system($pgserver_cmd_stop).should be_true
|
196
|
+
system($pgserver_cmd_start).should be_true
|
197
|
+
@tested_proc.call
|
198
|
+
end
|
199
|
+
end.to raise_error DISCONNECTED_ERROR
|
200
|
+
@tested_proc.call
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should fail to get last result asynchronously after server restart" do
|
204
|
+
@client.on_autoreconnect = proc {
|
205
|
+
EM::DefaultDeferrable.new.tap {|df| df.succeed }
|
206
|
+
}
|
207
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
208
|
+
system($pgserver_cmd_stop).should be_true
|
209
|
+
system($pgserver_cmd_start).should be_true
|
210
|
+
expect do
|
211
|
+
@client.get_last_result
|
212
|
+
end.to raise_error PG::ConnectionBad
|
213
|
+
@client.status.should be PG::CONNECTION_OK
|
214
|
+
@client.get_last_result.should be_nil
|
215
|
+
EM.stop
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should fail to get each result asynchronously after server restart" do
|
219
|
+
@client.on_autoreconnect = proc { true }
|
220
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
221
|
+
system($pgserver_cmd_stop).should be_true
|
222
|
+
system($pgserver_cmd_start).should be_true
|
223
|
+
result = @client.get_result
|
224
|
+
result.should be_an_instance_of PG::Result
|
225
|
+
expect do
|
226
|
+
result.check
|
227
|
+
end.to raise_error PG::Error
|
228
|
+
@client.status.should be PG::CONNECTION_OK
|
229
|
+
expect do
|
230
|
+
@client.get_result
|
231
|
+
end.to raise_error PG::ConnectionBad
|
232
|
+
@client.status.should be PG::CONNECTION_OK
|
233
|
+
@client.get_result.should be_nil
|
234
|
+
EM.stop
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should fail wait_for_notify while server restarts" do
|
238
|
+
@client.status.should be PG::CONNECTION_OK
|
239
|
+
@client.on_autoreconnect(&@on_autoreconnect)
|
240
|
+
f = Fiber.current
|
241
|
+
notify_flag = false
|
242
|
+
Fiber.new do
|
243
|
+
expect {
|
244
|
+
@client.wait_for_notify do
|
245
|
+
raise "This block should not be called"
|
246
|
+
end
|
247
|
+
}.to raise_error(PG::ConnectionBad)
|
248
|
+
@client.status.should be PG::CONNECTION_OK
|
249
|
+
Fiber.new do
|
250
|
+
@client.wait_for_notify do |name,|
|
251
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
252
|
+
notify_flag = true
|
253
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
254
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
255
|
+
f.resume
|
256
|
+
end.resume
|
257
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
258
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
259
|
+
end.resume
|
260
|
+
system($pgserver_cmd_stop).should be_true
|
261
|
+
system($pgserver_cmd_start).should be_true
|
262
|
+
Fiber.yield
|
263
|
+
notify_flag.should be_true
|
264
|
+
@tested_proc.call
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should fail wait_for_notify and finish slow query while server restarts" do
|
268
|
+
@client.status.should be PG::CONNECTION_OK
|
269
|
+
@client.on_autoreconnect = @on_autoreconnect
|
270
|
+
f = Fiber.current
|
271
|
+
notify_flag = false
|
272
|
+
query_flag = false
|
273
|
+
start_time = Time.now
|
274
|
+
Fiber.new do
|
275
|
+
result = @client.query('SELECT pg_sleep(2); SELECT 42')
|
276
|
+
result.should be_an_instance_of PG::Result
|
277
|
+
result.getvalue(0,0).to_i.should eq 42
|
278
|
+
(Time.now - start_time).should be > 2
|
279
|
+
query_flag = true
|
280
|
+
end.resume
|
281
|
+
Fiber.new do
|
282
|
+
expect {
|
283
|
+
@client.wait_for_notify do
|
284
|
+
raise "This block should not be called"
|
285
|
+
end
|
286
|
+
}.to raise_error(PG::ConnectionBad)
|
287
|
+
query_flag.should be_true
|
288
|
+
@client.status.should be PG::CONNECTION_OK
|
289
|
+
Fiber.new do
|
290
|
+
@client.wait_for_notify do |name,|
|
291
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
292
|
+
notify_flag = true
|
293
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
294
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
295
|
+
f.resume
|
296
|
+
end.resume
|
297
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
298
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
299
|
+
end.resume
|
300
|
+
system($pgserver_cmd_stop).should be_true
|
301
|
+
system($pgserver_cmd_start).should be_true
|
302
|
+
Fiber.yield
|
303
|
+
notify_flag.should be_true
|
304
|
+
@tested_proc.call
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should execute on_connect before on_autoreconnect after server restart" do
|
308
|
+
@client.on_connect.should be_nil
|
309
|
+
run_on_connect = false
|
310
|
+
@client.on_connect = proc do |client, is_async, is_reset|
|
311
|
+
client.should be_an_instance_of PG::EM::Client
|
312
|
+
is_async.should be_true
|
313
|
+
is_reset.should be_true
|
314
|
+
client.query('SELECT pg_database_size(current_database());') {
|
315
|
+
run_on_connect = true
|
316
|
+
}
|
317
|
+
end
|
318
|
+
@client.on_autoreconnect = proc do |client, ex|
|
319
|
+
run_on_connect.should be_true
|
320
|
+
@on_autoreconnect.call(client, ex)
|
321
|
+
end
|
322
|
+
system($pgserver_cmd_stop).should be_true
|
323
|
+
system($pgserver_cmd_start).should be_true
|
324
|
+
@tested_proc.call
|
325
|
+
EM.stop
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should skip on_autoreconnect when on_connect failed after server restart" do
|
329
|
+
run_on_connect = false
|
330
|
+
run_on_autoreconnect = false
|
331
|
+
@client.on_connect = proc do |client, is_async, is_reset|
|
332
|
+
client.should be_an_instance_of PG::EM::Client
|
333
|
+
is_async.should be_true
|
334
|
+
is_reset.should be_true
|
335
|
+
begin
|
336
|
+
client.query('SELLECT 1;')
|
337
|
+
ensure
|
338
|
+
run_on_connect = true
|
339
|
+
end
|
340
|
+
end
|
341
|
+
@client.on_autoreconnect = proc do |client, ex|
|
342
|
+
run_on_autoreconnect = true
|
343
|
+
end
|
344
|
+
system($pgserver_cmd_stop).should be_true
|
345
|
+
system($pgserver_cmd_start).should be_true
|
346
|
+
expect do
|
347
|
+
@client.exec_prepared('get_db_size')
|
348
|
+
end.to raise_error PG::SyntaxError
|
349
|
+
@client.status.should be PG::CONNECTION_OK
|
350
|
+
run_on_connect.should be_true
|
351
|
+
run_on_autoreconnect.should be_false
|
352
|
+
EM.stop
|
353
|
+
end
|
354
|
+
|
355
|
+
before(:all) do
|
356
|
+
@tested_proc = proc do
|
357
|
+
@client.exec_prepared('get_db_size') do |result|
|
358
|
+
result.should be_an_instance_of PG::Result
|
359
|
+
result[0]['pg_database_size'].to_i.should be > 0
|
360
|
+
end
|
361
|
+
end
|
362
|
+
@on_autoreconnect = proc do |client, ex|
|
363
|
+
client.prepare('get_db_size', 'SELECT pg_database_size(current_database());')
|
364
|
+
end
|
365
|
+
@options = {on_autoreconnect: @on_autoreconnect}
|
366
|
+
@client = PG::EM::Client.new(@options)
|
367
|
+
@client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
|
368
|
+
@on_autoreconnect.call @client
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe 'em-synchrony-pg with autoreconnect disabled' do
|
373
|
+
include_context 'em-synchrony-pg common'
|
374
|
+
|
375
|
+
it "should get database size using query" do
|
376
|
+
@tested_proc.call
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should not get database size using query after server restart" do
|
380
|
+
system($pgserver_cmd_stop).should be_true
|
381
|
+
system($pgserver_cmd_start).should be_true
|
382
|
+
expect {
|
383
|
+
@tested_proc.call
|
384
|
+
}.to raise_error DISCONNECTED_ERROR
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should get database size using query after manual connection reset" do
|
388
|
+
@client.status.should be PG::CONNECTION_BAD
|
389
|
+
@client.reset
|
390
|
+
@client.status.should be PG::CONNECTION_OK
|
391
|
+
@tested_proc.call
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should fail to get last result asynchronously after server restart" do
|
395
|
+
system($pgserver_cmd_stop).should be_true
|
396
|
+
system($pgserver_cmd_start).should be_true
|
397
|
+
begin
|
398
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
399
|
+
rescue PG::UnableToSend
|
400
|
+
@client.status.should be PG::CONNECTION_BAD
|
401
|
+
@client.get_last_result.should be_nil
|
402
|
+
else
|
403
|
+
expect do
|
404
|
+
@client.get_last_result
|
405
|
+
end.to raise_error PG::ConnectionBad
|
406
|
+
end
|
407
|
+
@client.status.should be PG::CONNECTION_BAD
|
408
|
+
@client.get_last_result.should be_nil
|
409
|
+
@client.reset
|
410
|
+
@client.status.should be PG::CONNECTION_OK
|
411
|
+
@client.get_last_result.should be_nil
|
412
|
+
EM.stop
|
413
|
+
end
|
414
|
+
|
415
|
+
it "should fail to get each result asynchronously after server restart" do
|
416
|
+
system($pgserver_cmd_stop).should be_true
|
417
|
+
system($pgserver_cmd_start).should be_true
|
418
|
+
begin
|
419
|
+
@client.send_query('SELECT pg_sleep(50); SELECT pg_database_size(current_database());')
|
420
|
+
rescue PG::UnableToSend
|
421
|
+
@client.status.should be PG::CONNECTION_BAD
|
422
|
+
@client.get_result.should be_nil
|
423
|
+
else
|
424
|
+
result = @client.get_result
|
425
|
+
result.should be_an_instance_of PG::Result
|
426
|
+
expect do
|
427
|
+
result.check
|
428
|
+
end.to raise_error PG::Error
|
429
|
+
@client.status.should be PG::CONNECTION_OK
|
430
|
+
expect do
|
431
|
+
@client.get_result
|
432
|
+
end.to raise_error PG::ConnectionBad
|
433
|
+
end
|
434
|
+
@client.status.should be PG::CONNECTION_BAD
|
435
|
+
@client.get_result.should be_nil
|
436
|
+
@client.status.should be PG::CONNECTION_BAD
|
437
|
+
@client.reset
|
438
|
+
@client.status.should be PG::CONNECTION_OK
|
439
|
+
@client.get_result.should be_nil
|
440
|
+
EM.stop
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should fail wait_for_notify while server restarts" do
|
444
|
+
@client.status.should be PG::CONNECTION_OK
|
445
|
+
f = Fiber.current
|
446
|
+
notify_flag = false
|
447
|
+
Fiber.new do
|
448
|
+
expect {
|
449
|
+
@client.wait_for_notify do
|
450
|
+
raise "This block should not be called"
|
451
|
+
end
|
452
|
+
}.to raise_error(PG::ConnectionBad)
|
453
|
+
@client.status.should be PG::CONNECTION_BAD
|
454
|
+
expect {
|
455
|
+
@client.wait_for_notify do
|
456
|
+
raise "This block should not be called"
|
457
|
+
end
|
458
|
+
}.to raise_error(PG::ConnectionBad)
|
459
|
+
@client.status.should be PG::CONNECTION_BAD
|
460
|
+
@client.reset
|
461
|
+
@client.status.should be PG::CONNECTION_OK
|
462
|
+
Fiber.new do
|
463
|
+
@client.wait_for_notify do |name,|
|
464
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
465
|
+
notify_flag = true
|
466
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
467
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
468
|
+
f.resume
|
469
|
+
end.resume
|
470
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
471
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
472
|
+
end.resume
|
473
|
+
system($pgserver_cmd_stop).should be_true
|
474
|
+
system($pgserver_cmd_start).should be_true
|
475
|
+
Fiber.yield
|
476
|
+
notify_flag.should be_true
|
477
|
+
end
|
478
|
+
|
479
|
+
it "should fail both wait_for_notify and slow query while server restarts" do
|
480
|
+
@client.status.should be PG::CONNECTION_OK
|
481
|
+
f = Fiber.current
|
482
|
+
notify_flag = false
|
483
|
+
query_flag = false
|
484
|
+
Fiber.new do
|
485
|
+
expect {
|
486
|
+
@client.query('SELECT pg_sleep(2); SELECT 42')
|
487
|
+
}.to raise_error(PG::ConnectionBad)
|
488
|
+
query_flag = true
|
489
|
+
end.resume
|
490
|
+
Fiber.new do
|
491
|
+
expect {
|
492
|
+
@client.wait_for_notify do
|
493
|
+
raise "This block should not be called"
|
494
|
+
end
|
495
|
+
}.to raise_error(PG::ConnectionBad)
|
496
|
+
query_flag.should be_true
|
497
|
+
@client.status.should be PG::CONNECTION_BAD
|
498
|
+
expect {
|
499
|
+
@client.wait_for_notify do
|
500
|
+
raise "This block should not be called"
|
501
|
+
end
|
502
|
+
}.to raise_error(PG::ConnectionBad)
|
503
|
+
@client.status.should be PG::CONNECTION_BAD
|
504
|
+
expect {
|
505
|
+
@client.query('SELECT 1')
|
506
|
+
}.to raise_error(PG::UnableToSend)
|
507
|
+
@client.reset
|
508
|
+
@client.status.should be PG::CONNECTION_OK
|
509
|
+
Fiber.new do
|
510
|
+
@client.wait_for_notify do |name,|
|
511
|
+
name.should eq 'em_synchrony_client_autoreconnect'
|
512
|
+
notify_flag = true
|
513
|
+
end.should eq 'em_synchrony_client_autoreconnect'
|
514
|
+
@client.query('UNLISTEN *').should be_an_instance_of PG::Result
|
515
|
+
f.resume
|
516
|
+
end.resume
|
517
|
+
@client.query('LISTEN em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
518
|
+
@client.query('NOTIFY em_synchrony_client_autoreconnect').should be_an_instance_of PG::Result
|
519
|
+
end.resume
|
520
|
+
system($pgserver_cmd_stop).should be_true
|
521
|
+
system($pgserver_cmd_start).should be_true
|
522
|
+
Fiber.yield
|
523
|
+
notify_flag.should be_true
|
524
|
+
end
|
525
|
+
|
526
|
+
it "should fail wait_for_notify when server was shutdown" do
|
527
|
+
@client.status.should be PG::CONNECTION_OK
|
528
|
+
@client.wait_for_notify(0.1) do
|
529
|
+
raise "This block should not be called"
|
530
|
+
end.should be_nil
|
531
|
+
system($pgserver_cmd_stop).should be_true
|
532
|
+
expect {
|
533
|
+
@client.wait_for_notify do
|
534
|
+
raise "This block should not be called"
|
535
|
+
end
|
536
|
+
}.to raise_error(PG::ConnectionBad)
|
537
|
+
@client.status.should be PG::CONNECTION_BAD
|
538
|
+
expect {
|
539
|
+
@client.wait_for_notify do
|
540
|
+
raise "This block should not be called"
|
541
|
+
end
|
542
|
+
}.to raise_error(PG::ConnectionBad)
|
543
|
+
@client.status.should be PG::CONNECTION_BAD
|
544
|
+
system($pgserver_cmd_start).should be_true
|
545
|
+
@client.status.should be PG::CONNECTION_BAD
|
546
|
+
@client.reset
|
547
|
+
@client.status.should be PG::CONNECTION_OK
|
548
|
+
end
|
549
|
+
|
550
|
+
before(:all) do
|
551
|
+
@tested_proc = proc do
|
552
|
+
@client.query('SELECT pg_database_size(current_database());') do |result|
|
553
|
+
result.should be_an_instance_of PG::Result
|
554
|
+
result[0]['pg_database_size'].to_i.should be > 0
|
555
|
+
end
|
556
|
+
end
|
557
|
+
@client = PG::EM::Client.new
|
558
|
+
@client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
|
559
|
+
end
|
560
|
+
end
|