perfectqueue 0.8.40 → 0.8.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +8 -0
- data/ChangeLog +7 -0
- data/Gemfile +1 -1
- data/README.md +2 -0
- data/lib/perfectqueue/multiprocess/child_process.rb +18 -17
- data/lib/perfectqueue/signal_queue.rb +2 -0
- data/lib/perfectqueue/signal_thread.rb +127 -0
- data/lib/perfectqueue/supervisor.rb +15 -14
- data/lib/perfectqueue/version.rb +1 -1
- data/lib/perfectqueue/worker.rb +14 -13
- data/lib/perfectqueue.rb +3 -0
- metadata +21 -36
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3193b8f7bd75661b9fe9c30b9cdadccebf0c2fbe
|
4
|
+
data.tar.gz: 86ec5d98cbe5a15dcf94093f607d3e91a68bbb2b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0fbc35db6a9eddba6873d1be42bc3d422e614936960930c641edd4cc57046c6b2b3636c13e183b15046db5b6f4ef00befa956c911134e94f6c2f9c8f03f03463
|
7
|
+
data.tar.gz: eb8db4f5259f780807b79387a0c5b7ab2904a5e300ff0a63d461fdf93691d43282c2f30f15bdd71edbc3a41c2d7ff993aa735ffe1667474e6da4d77b6d301fc1
|
data/.travis.yml
ADDED
data/ChangeLog
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# PerfectQueue
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/treasure-data/perfectqueue.svg?branch=master)](https://travis-ci.org/treasure-data/perfectqueue)
|
4
|
+
|
3
5
|
PerfectQueue is a highly available distributed queue built on top of RDBMS.
|
4
6
|
PerfectQueue provides similar API to Amazon SQS, while PerfectQueue focues on reliability and flexible scheduling rather than scalability.
|
5
7
|
|
@@ -95,36 +95,37 @@ module PerfectQueue
|
|
95
95
|
|
96
96
|
private
|
97
97
|
def install_signal_handlers
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
s = self
|
99
|
+
SignalThread.new do |st|
|
100
|
+
st.trap :TERM do
|
101
|
+
s.stop(false)
|
101
102
|
end
|
102
|
-
|
103
|
-
stop(false)
|
103
|
+
st.trap :INT do
|
104
|
+
s.stop(false)
|
104
105
|
end
|
105
106
|
|
106
|
-
|
107
|
-
stop(true)
|
107
|
+
st.trap :QUIT do
|
108
|
+
s.stop(true)
|
108
109
|
end
|
109
110
|
|
110
|
-
|
111
|
-
stop(false)
|
111
|
+
st.trap :USR1 do
|
112
|
+
s.stop(false)
|
112
113
|
end
|
113
114
|
|
114
|
-
|
115
|
-
stop(true)
|
115
|
+
st.trap :HUP do
|
116
|
+
s.stop(true)
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
|
-
stop(false)
|
119
|
+
st.trap :CONT do
|
120
|
+
s.stop(false)
|
120
121
|
end
|
121
122
|
|
122
|
-
|
123
|
-
stop(true)
|
123
|
+
st.trap :WINCH do
|
124
|
+
s.stop(true)
|
124
125
|
end
|
125
126
|
|
126
|
-
|
127
|
-
logrotated
|
127
|
+
st.trap :USR2 do
|
128
|
+
s.logrotated
|
128
129
|
end
|
129
130
|
|
130
131
|
trap :CHLD, "SIG_DFL"
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#
|
2
|
+
# PerfectQueue
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012-2013 Sadayuki Furuhashi
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module PerfectQueue
|
19
|
+
|
20
|
+
class SignalThread < Thread
|
21
|
+
def initialize(&block)
|
22
|
+
require 'thread'
|
23
|
+
|
24
|
+
@handlers = {}
|
25
|
+
|
26
|
+
@mutex = Mutex.new
|
27
|
+
@cond = ConditionVariable.new
|
28
|
+
@queue = []
|
29
|
+
@finished = false
|
30
|
+
|
31
|
+
block.call(self) if block
|
32
|
+
|
33
|
+
super(&method(:main))
|
34
|
+
end
|
35
|
+
|
36
|
+
def trap(sig, command=nil, &block)
|
37
|
+
# normalize signal names
|
38
|
+
sig = sig.to_s.upcase
|
39
|
+
if sig[0,3] == "SIG"
|
40
|
+
sig = sig[3..-1]
|
41
|
+
end
|
42
|
+
sig = sig.to_sym
|
43
|
+
|
44
|
+
old = @handlers[sig]
|
45
|
+
if block
|
46
|
+
Kernel.trap(sig) { signal_handler_main(sig) }
|
47
|
+
@handlers[sig] = block
|
48
|
+
else
|
49
|
+
Kernel.trap(sig, command)
|
50
|
+
@handlers.delete(sig)
|
51
|
+
end
|
52
|
+
|
53
|
+
old
|
54
|
+
end
|
55
|
+
|
56
|
+
def handlers
|
57
|
+
@handlers.dup
|
58
|
+
end
|
59
|
+
|
60
|
+
def stop
|
61
|
+
@mutex.synchronize do
|
62
|
+
@finished = true
|
63
|
+
@cond.broadcast
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def signal_handler_main(sig)
|
71
|
+
# here always creates new thread to avoid
|
72
|
+
# complicated race condition in signal handlers
|
73
|
+
Thread.new do
|
74
|
+
begin
|
75
|
+
enqueue(sig)
|
76
|
+
rescue => e
|
77
|
+
STDERR.print "#{e}\n"
|
78
|
+
e.backtrace.each do |bt|
|
79
|
+
STDERR.print "\t#{bt}\n"
|
80
|
+
STDERR.flush
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def main
|
88
|
+
until @finished
|
89
|
+
sig = nil
|
90
|
+
|
91
|
+
@mutex.synchronize do
|
92
|
+
while true
|
93
|
+
return if @finished
|
94
|
+
|
95
|
+
sig = @queue.shift
|
96
|
+
break if sig
|
97
|
+
|
98
|
+
@cond.wait(@mutex, 1)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
begin
|
103
|
+
@handlers[sig].call(sig)
|
104
|
+
rescue => e
|
105
|
+
STDERR.print "#{e}\n"
|
106
|
+
e.backtrace.each do |bt|
|
107
|
+
STDERR.print "\t#{bt}\n"
|
108
|
+
STDERR.flush
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
nil
|
114
|
+
|
115
|
+
ensure
|
116
|
+
@finished = false
|
117
|
+
end
|
118
|
+
|
119
|
+
def enqueue(sig)
|
120
|
+
@mutex.synchronize do
|
121
|
+
@queue << sig
|
122
|
+
@cond.broadcast
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
@@ -141,28 +141,29 @@ module PerfectQueue
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def install_signal_handlers(&block)
|
144
|
-
|
145
|
-
|
146
|
-
|
144
|
+
s = self
|
145
|
+
st = SignalThread.new do |st|
|
146
|
+
st.trap :TERM do
|
147
|
+
s.stop(false)
|
147
148
|
end
|
148
|
-
|
149
|
-
stop(false)
|
149
|
+
st.trap :INT do
|
150
|
+
s.stop(false)
|
150
151
|
end
|
151
152
|
|
152
|
-
|
153
|
-
stop(true)
|
153
|
+
st.trap :QUIT do
|
154
|
+
s.stop(true)
|
154
155
|
end
|
155
156
|
|
156
|
-
|
157
|
-
restart(false)
|
157
|
+
st.trap :USR1 do
|
158
|
+
s.restart(false)
|
158
159
|
end
|
159
160
|
|
160
|
-
|
161
|
-
restart(true)
|
161
|
+
st.trap :HUP do
|
162
|
+
s.restart(true)
|
162
163
|
end
|
163
164
|
|
164
|
-
|
165
|
-
logrotated
|
165
|
+
st.trap :USR2 do
|
166
|
+
s.logrotated
|
166
167
|
end
|
167
168
|
|
168
169
|
trap :CHLD, "SIG_IGN"
|
@@ -171,7 +172,7 @@ module PerfectQueue
|
|
171
172
|
begin
|
172
173
|
block.call
|
173
174
|
ensure
|
174
|
-
|
175
|
+
st.stop
|
175
176
|
end
|
176
177
|
end
|
177
178
|
end
|
data/lib/perfectqueue/version.rb
CHANGED
data/lib/perfectqueue/worker.rb
CHANGED
@@ -99,30 +99,31 @@ module PerfectQueue
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def install_signal_handlers
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
s = self
|
103
|
+
SignalThread.new do |st|
|
104
|
+
st.trap :TERM do
|
105
|
+
s.stop(false)
|
105
106
|
end
|
106
107
|
|
107
108
|
# override
|
108
|
-
|
109
|
-
detach
|
109
|
+
st.trap :INT do
|
110
|
+
s.detach
|
110
111
|
end
|
111
112
|
|
112
|
-
|
113
|
-
stop(true)
|
113
|
+
st.trap :QUIT do
|
114
|
+
s.stop(true)
|
114
115
|
end
|
115
116
|
|
116
|
-
|
117
|
-
restart(false)
|
117
|
+
st.trap :USR1 do
|
118
|
+
s.restart(false)
|
118
119
|
end
|
119
120
|
|
120
|
-
|
121
|
-
restart(true)
|
121
|
+
st.trap :HUP do
|
122
|
+
s.restart(true)
|
122
123
|
end
|
123
124
|
|
124
|
-
|
125
|
-
logrotated
|
125
|
+
st.trap :USR2 do
|
126
|
+
s.logrotated
|
126
127
|
end
|
127
128
|
end
|
128
129
|
end
|
data/lib/perfectqueue.rb
CHANGED
@@ -40,7 +40,10 @@ module PerfectQueue
|
|
40
40
|
:TaskStatus => 'perfectqueue/task_status',
|
41
41
|
:Worker => 'perfectqueue/worker',
|
42
42
|
:Supervisor => 'perfectqueue/supervisor',
|
43
|
+
# SignalQueue is obsolete because it does not run with ruby >= 2.0.0.
|
44
|
+
# See ddbf04c9 and use SignalThread instead.
|
43
45
|
:SignalQueue => 'perfectqueue/signal_queue',
|
46
|
+
:SignalThread => 'perfectqueue/signal_thread',
|
44
47
|
:VERSION => 'perfectqueue/version',
|
45
48
|
}.each_pair {|k,v|
|
46
49
|
autoload k, File.expand_path(v, File.dirname(__FILE__))
|
metadata
CHANGED
@@ -1,94 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perfectqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
5
|
-
prerelease:
|
4
|
+
version: 0.8.41
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Sadayuki Furuhashi
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: sequel
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 3.48.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 3.48.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.9.2
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.9.2
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 2.10.0
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 2.10.0
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: simplecov
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- - ~>
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 0.5.4
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 0.5.4
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: sqlite3
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- - ~>
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: 1.3.3
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- - ~>
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: 1.3.3
|
94
83
|
description: Highly available distributed cron built on RDBMS
|
@@ -98,7 +87,8 @@ executables:
|
|
98
87
|
extensions: []
|
99
88
|
extra_rdoc_files: []
|
100
89
|
files:
|
101
|
-
- .gitignore
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
102
92
|
- ChangeLog
|
103
93
|
- Gemfile
|
104
94
|
- LICENSE
|
@@ -129,6 +119,7 @@ files:
|
|
129
119
|
- lib/perfectqueue/queue.rb
|
130
120
|
- lib/perfectqueue/runner.rb
|
131
121
|
- lib/perfectqueue/signal_queue.rb
|
122
|
+
- lib/perfectqueue/signal_thread.rb
|
132
123
|
- lib/perfectqueue/supervisor.rb
|
133
124
|
- lib/perfectqueue/task.rb
|
134
125
|
- lib/perfectqueue/task_metadata.rb
|
@@ -145,33 +136,26 @@ files:
|
|
145
136
|
homepage: https://github.com/treasure-data/perfectqueue
|
146
137
|
licenses:
|
147
138
|
- Apache 2.0
|
139
|
+
metadata: {}
|
148
140
|
post_install_message:
|
149
141
|
rdoc_options: []
|
150
142
|
require_paths:
|
151
143
|
- lib
|
152
144
|
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
145
|
requirements:
|
155
|
-
- -
|
146
|
+
- - ">="
|
156
147
|
- !ruby/object:Gem::Version
|
157
148
|
version: '0'
|
158
|
-
segments:
|
159
|
-
- 0
|
160
|
-
hash: 2104551173355811922
|
161
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
-
none: false
|
163
150
|
requirements:
|
164
|
-
- -
|
151
|
+
- - ">="
|
165
152
|
- !ruby/object:Gem::Version
|
166
153
|
version: '0'
|
167
|
-
segments:
|
168
|
-
- 0
|
169
|
-
hash: 2104551173355811922
|
170
154
|
requirements: []
|
171
155
|
rubyforge_project:
|
172
|
-
rubygems_version:
|
156
|
+
rubygems_version: 2.4.5
|
173
157
|
signing_key:
|
174
|
-
specification_version:
|
158
|
+
specification_version: 4
|
175
159
|
summary: Highly available distributed cron built on RDBMS
|
176
160
|
test_files:
|
177
161
|
- spec/queue_spec.rb
|
@@ -179,3 +163,4 @@ test_files:
|
|
179
163
|
- spec/spec_helper.rb
|
180
164
|
- spec/stress.rb
|
181
165
|
- spec/supervisor_spec.rb
|
166
|
+
has_rdoc: false
|