perfectqueue 0.8.1 → 0.8.2

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.
data/ChangeLog CHANGED
@@ -1,4 +1,14 @@
1
1
 
2
+ == 2012-06-29 version 0.8.2
3
+
4
+ * 'process' type multiprocessor supports max_request_per_child option
5
+ * rdb_compat: heartbeat assumes UPDATE suceeded if 'timeout' is not changed
6
+ in case it was called within 1 second
7
+ * Child process ignores SIGCHLD
8
+ * Fixed Router not to match 'x' routing pattern with 'xy'
9
+ * Fixed child/task heartbeat timing calculation
10
+
11
+
2
12
  == 2012-06-25 version 0.8.1
3
13
 
4
14
  * Added autoload for PerfectQueue::VERSION
@@ -30,7 +30,7 @@ module PerfectQueue
30
30
  when Regexp
31
31
  # ok
32
32
  when String, Symbol
33
- pattern = /#{Regexp.escape(pattern)}/
33
+ pattern = /\A#{Regexp.escape(pattern)}\z/
34
34
  else
35
35
  raise ArguementError, "pattern should be String or Regexp but got #{pattern.class}: #{pattern.inspect}"
36
36
  end
@@ -213,12 +213,15 @@ SQL
213
213
  connect {
214
214
  n = @db["UPDATE `#{@table}` SET timeout=? WHERE id=? AND created_at IS NOT NULL;", next_timeout, key].update
215
215
  if n <= 0
216
- row = @db.fetch("SELECT id, created_at FROM `#{@table}` WHERE id=? LIMIT 1", key).first
216
+ row = @db.fetch("SELECT id, timeout, created_at FROM `#{@table}` WHERE id=? LIMIT 1", key).first
217
217
  if row == nil
218
- raise AlreadyFinishedError, "task key=#{key} already finished."
218
+ raise AlreadyFinishedError, "task key=#{key} does not exist or already finished."
219
219
  elsif row[:created_at] == -1
220
220
  raise CancelRequestedError, "task key=#{key} is cancel requested."
221
+ elsif row[:timeout] == next_timeout
222
+ # ok
221
223
  else
224
+ # row[:created_at] == null
222
225
  raise AlreadyFinishedError, "task key=#{key} already finished."
223
226
  end
224
227
  end
@@ -27,15 +27,18 @@ module PerfectQueue
27
27
  def initialize(runner, config, wpipe)
28
28
  @wpipe = wpipe
29
29
  @wpipe.sync = true
30
+ @request_per_child = 0
30
31
  super(runner, config)
31
32
  @sig = install_signal_handlers
32
33
  end
33
34
 
35
+ # override
34
36
  def run
35
37
  super
36
38
  @sig.shutdown
37
39
  end
38
40
 
41
+ # override
39
42
  def stop(immediate)
40
43
  @log.info "Exiting worker pid=#{Process.pid}"
41
44
  super
@@ -51,10 +54,12 @@ module PerfectQueue
51
54
  # do nothing
52
55
  end
53
56
 
57
+ # override
54
58
  def logrotated
55
59
  @log.reopen!
56
60
  end
57
61
 
62
+ # override
58
63
  def child_heartbeat
59
64
  @wpipe.write HEARTBEAT_PACKET
60
65
  rescue
@@ -66,6 +71,23 @@ module PerfectQueue
66
71
 
67
72
  HEARTBEAT_PACKET = [0].pack('C')
68
73
 
74
+ # override
75
+ def restart(immediate, config)
76
+ @max_request_per_child = config[:max_request_per_child] || nil
77
+ super
78
+ end
79
+
80
+ # override
81
+ def process(task)
82
+ super
83
+ if @max_request_per_child
84
+ @request_per_child += 1
85
+ if @request_per_child > @max_request_per_child
86
+ stop(false)
87
+ end
88
+ end
89
+ end
90
+
69
91
  private
70
92
  def install_signal_handlers
71
93
  SignalQueue.start do |sig|
@@ -99,6 +121,8 @@ module PerfectQueue
99
121
  sig.trap :USR2 do
100
122
  logrotated
101
123
  end
124
+
125
+ trap :CHLD, "SIG_DFL"
102
126
  end
103
127
  end
104
128
  end
@@ -68,7 +68,7 @@ module PerfectQueue
68
68
  @log.error "Heartbeat pipe is closed. Restarting child process."
69
69
  c.start_killing(true)
70
70
  rescue
71
- @log.error "Unknown error: #{$!.class}: #{$!}. Restarting child process."
71
+ @log.error "Unknown error: #{$!.class}: #{$!}: Restarting child process."
72
72
  $!.backtrace.each {|bt| @log.warn "\t#{bt}" }
73
73
  c.start_killing(false)
74
74
  end
@@ -94,7 +94,7 @@ module PerfectQueue
94
94
  end
95
95
  }
96
96
  rescue
97
- @log.error "Unknown error #{$!.class}: #{$!}. Exiting worker pid=#{Process.pid}"
97
+ @log.error "Unknown error #{$!.class}: #{$!}: Exiting worker pid=#{Process.pid}"
98
98
  $!.backtrace.each {|bt| @log.warn "\t#{bt}" }
99
99
  ensure
100
100
  @tm.stop
@@ -115,19 +115,20 @@ module PerfectQueue
115
115
  next_task_heartbeat = @last_task_heartbeat + @task_heartbeat_interval
116
116
  next_time = [next_child_heartbeat, next_task_heartbeat].min
117
117
  else
118
+ next_task_heartbeat = nil
118
119
  next_time = next_child_heartbeat
119
120
  end
120
121
 
121
- next_wait = [1, next_time - now].max
122
- @cond.wait(next_wait) if next_wait > 0 # TODO timeout doesn't work?
122
+ next_wait = next_time - now
123
+ @cond.wait(next_wait) if next_wait > 0
123
124
 
124
125
  now = Time.now.to_i
125
- if @task && next_task_heartbeat && now <= next_task_heartbeat
126
+ if @task && next_task_heartbeat && next_task_heartbeat <= now
126
127
  task_heartbeat
127
128
  @last_task_heartbeat = now
128
129
  end
129
130
 
130
- if now <= next_child_heartbeat
131
+ if next_child_heartbeat <= now
131
132
  @child_heartbeat.call # will recursive lock
132
133
  @last_child_heartbeat = now
133
134
  end
@@ -1,3 +1,3 @@
1
1
  module PerfectQueue
2
- VERSION = "0.8.1"
2
+ VERSION = "0.8.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfectqueue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-25 00:00:00.000000000Z
12
+ date: 2012-06-29 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
16
- requirement: &70128708982980 !ruby/object:Gem::Requirement
16
+ requirement: &70175585314980 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.26.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70128708982980
24
+ version_requirements: *70175585314980
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70128708981280 !ruby/object:Gem::Requirement
27
+ requirement: &70175571565720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70128708981280
35
+ version_requirements: *70175571565720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70128708976640 !ruby/object:Gem::Requirement
38
+ requirement: &70175571565260 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.10.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70128708976640
46
+ version_requirements: *70175571565260
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: simplecov
49
- requirement: &70128708973780 !ruby/object:Gem::Requirement
49
+ requirement: &70175571564800 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.5.4
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70128708973780
57
+ version_requirements: *70175571564800
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sqlite3
60
- requirement: &70128708967780 !ruby/object:Gem::Requirement
60
+ requirement: &70175571564340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 1.3.3
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70128708967780
68
+ version_requirements: *70175571564340
69
69
  description: Highly available distributed cron built on RDBMS
70
70
  email: frsyuki@gmail.com
71
71
  executables: