perfectqueue 0.8.50 → 0.8.51

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f2a4de693be6fb67cec8c761d949996d4aab365
4
- data.tar.gz: 9ae56885f1e52d7e5e685e754ae3ec971d0abc05
3
+ metadata.gz: a2c5312dd385fbd06f7c00fc52c5661878de5d0e
4
+ data.tar.gz: c73dfc2576ef192056f9e09810c95bbd5f57640a
5
5
  SHA512:
6
- metadata.gz: 9cf308fbeaced67ee174de205e12d443ae96fcd695406c217cd6e254fcdba31632850ec734cab875126cb79e474b90642bde7a47b8a821665750f7e72bc4e0f4
7
- data.tar.gz: c95228db876ba2427b1b2b288abd76cb245583afabaaadb827bdd29bffa84cfb4a8830a6e6f5a0058b6c068882cfe9b8556102d3c959b3dd60c8b9c5253106a1
6
+ metadata.gz: eadcea4ea3b019cb9a76b9ec949d3d7eb7eb439479dbe8ced5a746d2c8e8fbb5f4e434307f84ee966e0f216c48a34c9fb927167ef51563fc593e12567fc64806
7
+ data.tar.gz: 563da9974f2d64efa75c5c515da14f9b45a794fec83d9ef4c95941f90b89ddeb99678464f43fa2683e1fa404a57e056ab22923b40a53ea55f3b735ab5a192c79
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ == 2016-10-24 version 0.8.51
2
+
3
+ * Retry on temporary DatabaseConnectionError (#59)
4
+
1
5
  == 2016-08-18 version 0.8.50
2
6
 
3
7
  * Decrease GET_LOCK timeout from 60 to 10 seconds
@@ -21,6 +21,8 @@ module PerfectQueue::Backend
21
21
  host: u.host,
22
22
  port: u.port ? u.port.to_i : 3306
23
23
  }
24
+ @pq_connect_timeout = config.fetch(:pq_connect_timeout, 20)
25
+ options[:connect_timeout] = config.fetch(:connect_timeout, 3)
24
26
  options[:sslca] = config[:sslca] if config[:sslca]
25
27
  db_name = u.path.split('/')[1]
26
28
  @db = Sequel.mysql2(db_name, options)
@@ -54,23 +56,31 @@ module PerfectQueue::Backend
54
56
  end
55
57
 
56
58
  private
57
- def connect(&block)
59
+ def connect
60
+ tmax = Process.clock_gettime(Process::CLOCK_REALTIME, :second) + @pq_connect_timeout
58
61
  @mutex.synchronize do
59
62
  retry_count = 0
60
63
  begin
61
- block.call
64
+ yield
65
+ rescue Sequel::DatabaseConnectionError
66
+ if (retry_count += 1) < MAX_RETRY && tmax > Process.clock_gettime(Process::CLOCK_REALTIME, :second)
67
+ STDERR.puts "#{$!}\n retrying."
68
+ sleep 2
69
+ retry
70
+ end
71
+ STDERR.puts "#{$!}\n abort."
72
+ raise
62
73
  rescue
63
74
  # workaround for "Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction" error
64
75
  if $!.to_s.include?('try restarting transaction')
65
- err = ([$!] + $!.backtrace.map {|bt| " #{bt}" }).join("\n")
76
+ err = $!.backtrace.map{|bt| " #{bt}" }.unshift($!).join("\n")
66
77
  retry_count += 1
67
78
  if retry_count < MAX_RETRY
68
- STDERR.puts err + "\n retrying."
79
+ STDERR.puts "#{err}\n retrying."
69
80
  sleep 0.5
70
81
  retry
71
- else
72
- STDERR.puts err + "\n abort."
73
82
  end
83
+ STDERR.puts "#{err}\n abort."
74
84
  end
75
85
  raise
76
86
  ensure
@@ -42,6 +42,7 @@ module PerfectQueue
42
42
  def initialize(client, config)
43
43
  super
44
44
 
45
+ @pq_connect_timeout = config.fetch(:pq_connect_timeout, 20)
45
46
  url = config[:url]
46
47
  @table = config[:table]
47
48
  unless @table
@@ -49,7 +50,9 @@ module PerfectQueue
49
50
  end
50
51
 
51
52
  if /\Amysql2:/i =~ url
52
- @db = Sequel.connect(url, {max_connections: 1, sslca: config[:sslca]})
53
+ options = {max_connections: 1, sslca: config[:sslca]}
54
+ options[:connect_timeout] = config.fetch(:connect_timeout, 3)
55
+ @db = Sequel.connect(url, options)
53
56
  if config.fetch(:use_connection_pooling, nil) != nil
54
57
  @use_connection_pooling = !!config[:use_connection_pooling]
55
58
  else
@@ -339,7 +342,7 @@ SQL
339
342
  end
340
343
 
341
344
  protected
342
- def connect_locked(&block)
345
+ def connect_locked
343
346
  connect {
344
347
  locked = false
345
348
 
@@ -349,7 +352,7 @@ SQL
349
352
  locked = true
350
353
  end
351
354
 
352
- return block.call
355
+ return yield
353
356
  ensure
354
357
  if @use_connection_pooling && locked
355
358
  @table_unlock.call
@@ -358,16 +361,25 @@ SQL
358
361
  }
359
362
  end
360
363
 
361
- def connect(&block)
364
+ def connect
362
365
  now = Time.now.to_i
366
+ tmax = now + @pq_connect_timeout
363
367
  @mutex.synchronize do
364
368
  # keepalive_timeout
365
369
  @db.disconnect if now - @last_time > KEEPALIVE
366
370
 
367
371
  count = 0
368
372
  begin
369
- block.call
373
+ yield
370
374
  @last_time = now
375
+ rescue Sequel::DatabaseConnectionError
376
+ if (count += 1) < MAX_RETRY && tmax > Time.now.to_i
377
+ STDERR.puts "#{$!}\n retrying."
378
+ sleep 2
379
+ retry
380
+ end
381
+ STDERR.puts "#{$!}\n abort."
382
+ raise
371
383
  rescue
372
384
  # workaround for "Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction" error
373
385
  if $!.to_s.include?('try restarting transaction')
@@ -1,3 +1,3 @@
1
1
  module PerfectQueue
2
- VERSION = "0.8.50"
2
+ VERSION = "0.8.51"
3
3
  end
@@ -65,5 +65,19 @@ describe Backend::RDBBackend do
65
65
  end.to raise_error(RuntimeError)
66
66
  end
67
67
  end
68
+ context 'cannot connect' do
69
+ let (:uri){ 'mysql2://root:@nonexistent/perfectqueue_test' }
70
+ let (:db) do
71
+ Backend::RDBBackend.new(uri, table)
72
+ end
73
+ it 'raises Sequel::DatabaseConnectionError' do
74
+ allow(STDERR).to receive(:puts)
75
+ slept = 0
76
+ expect(db).to receive(:sleep).exactly(9).times{|n| slept += n }
77
+ expect(db.db).to receive(:connect).exactly(10).times.and_call_original
78
+ expect{ db.__send__(:connect){ db.db.run('SELECT 1;') } }.to raise_error(Sequel::DatabaseConnectionError)
79
+ expect(slept).to be < 30
80
+ end
81
+ end
68
82
  end
69
83
  end
@@ -376,6 +376,18 @@ describe Backend::RDBCompatBackend do
376
376
  end
377
377
  end.to raise_error(RuntimeError)
378
378
  end
379
+ context 'cannot connect' do
380
+ let (:config){ {url: 'mysql2://root:@nonexistent/perfectqueue_test', table: table} }
381
+ it 'raises Sequel::DatabaseConnectionError' do
382
+ allow(STDERR).to receive(:puts)
383
+ d = Backend::RDBCompatBackend.new(client, config)
384
+ slept = 0
385
+ expect(d).to receive(:sleep).exactly(9).times{|n| slept += n }
386
+ expect(d.db).to receive(:connect).exactly(10).times.and_call_original
387
+ expect{ d.__send__(:connect){ d.db.run('SELECT 1;') } }.to raise_error(Sequel::DatabaseConnectionError)
388
+ expect(slept).to eq(18)
389
+ end
390
+ end
379
391
  end
380
392
  end
381
393
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfectqueue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.50
4
+ version: 0.8.51
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-17 00:00:00.000000000 Z
11
+ date: 2016-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel