procrastinate 0.5.0 → 0.6.0
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/HISTORY.txt +6 -0
- data/README +1 -1
- data/lib/procrastinate/process_manager.rb +20 -36
- data/lib/procrastinate/process_manager/child_process.rb +21 -0
- metadata +28 -60
- data/Rakefile +0 -36
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d211f3ecc75813707fd6acdb559783e5b1aa7124
|
4
|
+
data.tar.gz: 863ff06f3edb224c5edca1f38d88455a7c1c844f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7adc67259467bdfc350ea453de21574447deabff894ad65d80586b096a6306390be1729a06e5bdd00c61423ebd6bcb31835ef2efcdb1515b7057fd32acdac8a4
|
7
|
+
data.tar.gz: 62e94303c101c092b49efdb3f759169075f03e2972a3ec3ffe4d9c77d2973e0b12fe1137dc5cf98fc19a3ff9f2c0927bf03cc916aeb8cdebedc34fa855b517e7
|
data/HISTORY.txt
CHANGED
data/README
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
|
2
2
|
require 'state_machine'
|
3
|
-
require 'cod'
|
4
3
|
|
5
4
|
# Dispatches and handles tasks and task completion. Only low level unixy
|
6
5
|
# manipulation here, no strategy. The only methods you should call from the
|
@@ -23,9 +22,6 @@ class Procrastinate::ProcessManager
|
|
23
22
|
|
24
23
|
# All presently running children
|
25
24
|
@children = {}
|
26
|
-
|
27
|
-
# Master should read from @master, Children write to @child
|
28
|
-
@master, @child = Cod.pipe.split
|
29
25
|
end
|
30
26
|
|
31
27
|
# Sets up resource usage for dispatcher. You must call this before dispatcher
|
@@ -95,21 +91,31 @@ class Procrastinate::ProcessManager
|
|
95
91
|
cp_read_end = control_pipe.first
|
96
92
|
|
97
93
|
loop do # until we have input in the cp_read_end (control_pipe)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
94
|
+
io_map = children.inject({}) { |map, (_, child)|
|
95
|
+
map[child.master_pipe] = child; map }
|
96
|
+
|
97
|
+
ready, _, _ = IO.select(io_map.keys + [cp_read_end], [], [], 0.1)
|
98
|
+
next unless ready
|
99
|
+
|
100
|
+
# Process all messages that were sent from our childs to us.
|
101
|
+
ready.each { |io|
|
102
|
+
next if io == cp_read_end
|
104
103
|
|
104
|
+
child = io_map[io]
|
105
|
+
|
106
|
+
fail "Assert: All IOs correspond to a child" unless child
|
107
|
+
child.read_message
|
108
|
+
}
|
109
|
+
|
105
110
|
# Send the tracking code for the child processes the final notifications
|
106
111
|
# and remove them from the children hash. At this point we know that
|
107
112
|
# no messages are waiting in the child queue.
|
108
113
|
finalize_children
|
109
114
|
|
110
|
-
if ready.
|
115
|
+
if ready.include?(cp_read_end)
|
111
116
|
# Consume the data (not important)
|
112
117
|
cp_read_end.read_nonblock(1024)
|
118
|
+
# And return to our caller. This is the event we've been waiting for.
|
113
119
|
return
|
114
120
|
end
|
115
121
|
end
|
@@ -124,28 +130,6 @@ class Procrastinate::ProcessManager
|
|
124
130
|
child.removable? }
|
125
131
|
end
|
126
132
|
|
127
|
-
def read_child_messages
|
128
|
-
loop do
|
129
|
-
ready = Cod.select(0.1, @master)
|
130
|
-
break unless ready
|
131
|
-
|
132
|
-
handle_message @master.get
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Called for every message sent from a child. The +msg+ param here is a string
|
137
|
-
# that still needs decoding.
|
138
|
-
#
|
139
|
-
def handle_message(msg)
|
140
|
-
pid, obj = msg
|
141
|
-
|
142
|
-
if child=children[pid]
|
143
|
-
child.incoming_message(obj)
|
144
|
-
else
|
145
|
-
warn "Communication from child #{pid} received, but child is gone."
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
133
|
# Calls completion handlers for all the childs that have now exited.
|
150
134
|
#
|
151
135
|
def reap_childs
|
@@ -183,12 +167,13 @@ class Procrastinate::ProcessManager
|
|
183
167
|
# Tasks that are interested in getting messages from their childs must
|
184
168
|
# provide a result object that handles incoming 'result' messages.
|
185
169
|
result = task.result
|
170
|
+
child_process = ChildProcess.new(completion_handler, result)
|
186
171
|
|
187
172
|
pid = fork do
|
188
173
|
cleanup
|
189
174
|
|
190
175
|
if result
|
191
|
-
endpoint = lambda { |obj|
|
176
|
+
endpoint = lambda { |obj| child_process.send_message(obj) }
|
192
177
|
task.run(endpoint)
|
193
178
|
else
|
194
179
|
task.run(nil)
|
@@ -204,8 +189,7 @@ class Procrastinate::ProcessManager
|
|
204
189
|
# The spawning is done in the same thread as the reaping is done. This is
|
205
190
|
# why no race condition to the following line exists. (or in other code,
|
206
191
|
# for that matter.)
|
207
|
-
children[pid] =
|
208
|
-
tap { |s| s.start }
|
192
|
+
children[pid] = child_process.tap { |s| s.start }
|
209
193
|
end
|
210
194
|
|
211
195
|
# Gets executed in child process to clean up file handles and pipes that the
|
@@ -4,9 +4,13 @@
|
|
4
4
|
#
|
5
5
|
Procrastinate::ProcessManager::ChildProcess =
|
6
6
|
Struct.new(:handler, :result, :state) do
|
7
|
+
|
8
|
+
attr_reader :master_pipe, :child_pipe
|
7
9
|
|
8
10
|
def initialize(handler, result)
|
9
11
|
super(handler, result, "new")
|
12
|
+
|
13
|
+
@master_pipe, @child_pipe = IO.pipe
|
10
14
|
end
|
11
15
|
|
12
16
|
state_machine :state, :initial => :new do
|
@@ -33,6 +37,10 @@ Procrastinate::ProcessManager::ChildProcess =
|
|
33
37
|
#
|
34
38
|
def notify_result
|
35
39
|
result.process_died if result
|
40
|
+
|
41
|
+
# The child is now officially dead, so we don't need these anymore:
|
42
|
+
@master_pipe.close
|
43
|
+
@child_pipe.close
|
36
44
|
end
|
37
45
|
|
38
46
|
# Handles incoming messages from the tasks process.
|
@@ -40,4 +48,17 @@ Procrastinate::ProcessManager::ChildProcess =
|
|
40
48
|
def incoming_message(obj)
|
41
49
|
result.incoming_message(obj) if result
|
42
50
|
end
|
51
|
+
|
52
|
+
# Read and process a message from the process that is connected to this
|
53
|
+
# object. Normally, we would make sure that such a message is indeed waiting
|
54
|
+
# on the master_pipe by means of an IO select.
|
55
|
+
#
|
56
|
+
def read_message
|
57
|
+
msg = Marshal.load(master_pipe)
|
58
|
+
incoming_message(msg)
|
59
|
+
end
|
60
|
+
|
61
|
+
def send_message obj
|
62
|
+
Marshal.dump(obj, child_pipe)
|
63
|
+
end
|
43
64
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: procrastinate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.6.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kaspar Schiess
|
@@ -10,136 +9,106 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2013-11-20 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: state_machine
|
17
|
-
prerelease: false
|
18
16
|
requirement: !ruby/object:Gem::Requirement
|
19
17
|
requirements:
|
20
18
|
- - ~>
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '1.1'
|
23
|
-
none: false
|
24
21
|
type: :runtime
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.1'
|
30
|
-
none: false
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
name: cod
|
33
22
|
prerelease: false
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
35
|
-
requirements:
|
36
|
-
- - ~>
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
version: '0.5'
|
39
|
-
none: false
|
40
|
-
type: :runtime
|
41
23
|
version_requirements: !ruby/object:Gem::Requirement
|
42
24
|
requirements:
|
43
25
|
- - ~>
|
44
26
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
46
|
-
none: false
|
27
|
+
version: '1.1'
|
47
28
|
- !ruby/object:Gem::Dependency
|
48
29
|
name: rake
|
49
|
-
prerelease: false
|
50
30
|
requirement: !ruby/object:Gem::Requirement
|
51
31
|
requirements:
|
52
|
-
- -
|
32
|
+
- - '>='
|
53
33
|
- !ruby/object:Gem::Version
|
54
34
|
version: '0'
|
55
|
-
none: false
|
56
35
|
type: :development
|
36
|
+
prerelease: false
|
57
37
|
version_requirements: !ruby/object:Gem::Requirement
|
58
38
|
requirements:
|
59
|
-
- -
|
39
|
+
- - '>='
|
60
40
|
- !ruby/object:Gem::Version
|
61
41
|
version: '0'
|
62
|
-
none: false
|
63
42
|
- !ruby/object:Gem::Dependency
|
64
43
|
name: rspec
|
65
|
-
prerelease: false
|
66
44
|
requirement: !ruby/object:Gem::Requirement
|
67
45
|
requirements:
|
68
|
-
- -
|
46
|
+
- - '>='
|
69
47
|
- !ruby/object:Gem::Version
|
70
48
|
version: '0'
|
71
|
-
none: false
|
72
49
|
type: :development
|
50
|
+
prerelease: false
|
73
51
|
version_requirements: !ruby/object:Gem::Requirement
|
74
52
|
requirements:
|
75
|
-
- -
|
53
|
+
- - '>='
|
76
54
|
- !ruby/object:Gem::Version
|
77
55
|
version: '0'
|
78
|
-
none: false
|
79
56
|
- !ruby/object:Gem::Dependency
|
80
57
|
name: flexmock
|
81
|
-
prerelease: false
|
82
58
|
requirement: !ruby/object:Gem::Requirement
|
83
59
|
requirements:
|
84
|
-
- -
|
60
|
+
- - '>='
|
85
61
|
- !ruby/object:Gem::Version
|
86
62
|
version: '0'
|
87
|
-
none: false
|
88
63
|
type: :development
|
64
|
+
prerelease: false
|
89
65
|
version_requirements: !ruby/object:Gem::Requirement
|
90
66
|
requirements:
|
91
|
-
- -
|
67
|
+
- - '>='
|
92
68
|
- !ruby/object:Gem::Version
|
93
69
|
version: '0'
|
94
|
-
none: false
|
95
70
|
- !ruby/object:Gem::Dependency
|
96
71
|
name: guard
|
97
|
-
prerelease: false
|
98
72
|
requirement: !ruby/object:Gem::Requirement
|
99
73
|
requirements:
|
100
|
-
- -
|
74
|
+
- - '>='
|
101
75
|
- !ruby/object:Gem::Version
|
102
76
|
version: '0'
|
103
|
-
none: false
|
104
77
|
type: :development
|
78
|
+
prerelease: false
|
105
79
|
version_requirements: !ruby/object:Gem::Requirement
|
106
80
|
requirements:
|
107
|
-
- -
|
81
|
+
- - '>='
|
108
82
|
- !ruby/object:Gem::Version
|
109
83
|
version: '0'
|
110
|
-
none: false
|
111
84
|
- !ruby/object:Gem::Dependency
|
112
85
|
name: growl
|
113
|
-
prerelease: false
|
114
86
|
requirement: !ruby/object:Gem::Requirement
|
115
87
|
requirements:
|
116
|
-
- -
|
88
|
+
- - '>='
|
117
89
|
- !ruby/object:Gem::Version
|
118
90
|
version: '0'
|
119
|
-
none: false
|
120
91
|
type: :development
|
92
|
+
prerelease: false
|
121
93
|
version_requirements: !ruby/object:Gem::Requirement
|
122
94
|
requirements:
|
123
|
-
- -
|
95
|
+
- - '>='
|
124
96
|
- !ruby/object:Gem::Version
|
125
97
|
version: '0'
|
126
|
-
none: false
|
127
98
|
- !ruby/object:Gem::Dependency
|
128
99
|
name: yard
|
129
|
-
prerelease: false
|
130
100
|
requirement: !ruby/object:Gem::Requirement
|
131
101
|
requirements:
|
132
|
-
- -
|
102
|
+
- - '>='
|
133
103
|
- !ruby/object:Gem::Version
|
134
104
|
version: '0'
|
135
|
-
none: false
|
136
105
|
type: :development
|
106
|
+
prerelease: false
|
137
107
|
version_requirements: !ruby/object:Gem::Requirement
|
138
108
|
requirements:
|
139
|
-
- -
|
109
|
+
- - '>='
|
140
110
|
- !ruby/object:Gem::Version
|
141
111
|
version: '0'
|
142
|
-
none: false
|
143
112
|
description:
|
144
113
|
email:
|
145
114
|
- kaspar.schiess@absurd.li
|
@@ -151,7 +120,6 @@ extra_rdoc_files:
|
|
151
120
|
files:
|
152
121
|
- HISTORY.txt
|
153
122
|
- LICENSE
|
154
|
-
- Rakefile
|
155
123
|
- README
|
156
124
|
- lib/procrastinate/implicit.rb
|
157
125
|
- lib/procrastinate/lock.rb
|
@@ -178,7 +146,9 @@ files:
|
|
178
146
|
- examples/simple.rb
|
179
147
|
- examples/throttled.rb
|
180
148
|
homepage: http://github.com/kschiess/procrastinate
|
181
|
-
licenses:
|
149
|
+
licenses:
|
150
|
+
- MIT
|
151
|
+
metadata: {}
|
182
152
|
post_install_message:
|
183
153
|
rdoc_options:
|
184
154
|
- --main
|
@@ -187,21 +157,19 @@ require_paths:
|
|
187
157
|
- lib
|
188
158
|
required_ruby_version: !ruby/object:Gem::Requirement
|
189
159
|
requirements:
|
190
|
-
- -
|
160
|
+
- - '>='
|
191
161
|
- !ruby/object:Gem::Version
|
192
162
|
version: '0'
|
193
|
-
none: false
|
194
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
164
|
requirements:
|
196
|
-
- -
|
165
|
+
- - '>='
|
197
166
|
- !ruby/object:Gem::Version
|
198
167
|
version: '0'
|
199
|
-
none: false
|
200
168
|
requirements: []
|
201
169
|
rubyforge_project:
|
202
|
-
rubygems_version:
|
170
|
+
rubygems_version: 2.0.6
|
203
171
|
signing_key:
|
204
|
-
specification_version:
|
172
|
+
specification_version: 4
|
205
173
|
summary: Framework to run tasks in separate processes.
|
206
174
|
test_files: []
|
207
175
|
has_rdoc:
|
data/Rakefile
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require "rubygems"
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
require 'rubygems/package_task'
|
4
|
-
require 'rake/clean'
|
5
|
-
|
6
|
-
desc "Run all tests: Exhaustive."
|
7
|
-
RSpec::Core::RakeTask.new
|
8
|
-
|
9
|
-
task :default => :spec
|
10
|
-
|
11
|
-
task :stats do
|
12
|
-
%w(lib spec).each do |path|
|
13
|
-
printf "%10s:", path
|
14
|
-
system %Q(find #{path} -name "*.rb" | xargs wc -l | grep total)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'yard'
|
19
|
-
YARD::Rake::YardocTask.new do |t|
|
20
|
-
# t.files = ['lib/**/*.rb']
|
21
|
-
# t.options = ['--any', '--extra', '--opts'] # optional
|
22
|
-
end
|
23
|
-
|
24
|
-
desc 'Clear out RDoc'
|
25
|
-
task :clean => [:clobber_package]
|
26
|
-
|
27
|
-
# This task actually builds the gem.
|
28
|
-
task :gem => :spec
|
29
|
-
spec = eval(File.read('procrastinate.gemspec'))
|
30
|
-
|
31
|
-
desc "Generate the gem package."
|
32
|
-
Gem::PackageTask.new(spec) do |pkg|
|
33
|
-
# pkg.need_tar = true
|
34
|
-
end
|
35
|
-
|
36
|
-
CLEAN << 'doc'
|