procrastinate 0.4.1 → 0.5.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.
- data/HISTORY.txt +2 -1
- data/Rakefile +8 -11
- data/examples/server.rb +31 -0
- data/lib/procrastinate.rb +2 -1
- data/lib/procrastinate/implicit.rb +19 -16
- data/lib/procrastinate/process_manager.rb +20 -5
- data/lib/procrastinate/scheduler.rb +59 -13
- data/lib/procrastinate/server.rb +78 -0
- data/lib/procrastinate/task/callable.rb +1 -1
- metadata +88 -40
data/HISTORY.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "rubygems"
|
2
|
-
require "rdoc/task"
|
3
2
|
require 'rspec/core/rake_task'
|
4
3
|
require 'rubygems/package_task'
|
4
|
+
require 'rake/clean'
|
5
5
|
|
6
6
|
desc "Run all tests: Exhaustive."
|
7
7
|
RSpec::Core::RakeTask.new
|
@@ -15,19 +15,14 @@ task :stats do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
rdoc.options << '--fmt' << 'shtml' # explictly set shtml generator
|
23
|
-
rdoc.template = 'direct' # lighter template used on railsapi.com
|
24
|
-
rdoc.main = "README"
|
25
|
-
rdoc.rdoc_files.include("README", "lib/**/*.rb")
|
26
|
-
rdoc.rdoc_dir = "rdoc"
|
18
|
+
require 'yard'
|
19
|
+
YARD::Rake::YardocTask.new do |t|
|
20
|
+
# t.files = ['lib/**/*.rb']
|
21
|
+
# t.options = ['--any', '--extra', '--opts'] # optional
|
27
22
|
end
|
28
23
|
|
29
24
|
desc 'Clear out RDoc'
|
30
|
-
task :clean => [:
|
25
|
+
task :clean => [:clobber_package]
|
31
26
|
|
32
27
|
# This task actually builds the gem.
|
33
28
|
task :gem => :spec
|
@@ -37,3 +32,5 @@ desc "Generate the gem package."
|
|
37
32
|
Gem::PackageTask.new(spec) do |pkg|
|
38
33
|
# pkg.need_tar = true
|
39
34
|
end
|
35
|
+
|
36
|
+
CLEAN << 'doc'
|
data/examples/server.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
|
4
|
+
require 'procrastinate'
|
5
|
+
|
6
|
+
# * murder lazies
|
7
|
+
# * maintain worker count
|
8
|
+
|
9
|
+
scheduler = Procrastinate::Scheduler.start
|
10
|
+
scheduler.spawn_workers(6) {
|
11
|
+
# Worker body
|
12
|
+
loop do
|
13
|
+
puts "Hiho from worker #{Process.pid}."
|
14
|
+
sleep rand(1.0) * 3
|
15
|
+
end
|
16
|
+
}
|
17
|
+
|
18
|
+
# Wait around until something important happens
|
19
|
+
r, w = IO.pipe
|
20
|
+
trap('QUIT') { w.write '.' }
|
21
|
+
|
22
|
+
loop do
|
23
|
+
IO.select([r], nil, nil)
|
24
|
+
r.read_nonblock(1000)
|
25
|
+
|
26
|
+
# When we reach this point, a QUIT signal has been sent to the process.
|
27
|
+
# Abort.
|
28
|
+
break
|
29
|
+
end
|
30
|
+
|
31
|
+
scheduler.shutdown
|
data/lib/procrastinate.rb
CHANGED
@@ -2,57 +2,58 @@
|
|
2
2
|
require 'procrastinate'
|
3
3
|
|
4
4
|
module Procrastinate
|
5
|
-
# call-seq:
|
6
|
-
# Procrastinate.scheduler => scheduler
|
7
|
-
#
|
8
5
|
# Returns the scheduler instance. When using procrastinate/implicit, there
|
9
6
|
# is one global scheduler to your ruby process, this one.
|
7
|
+
#
|
8
|
+
# @return [Scheduler] singleton scheduler for implicit scheduling.
|
10
9
|
#
|
11
10
|
def scheduler
|
12
11
|
@scheduler ||= Scheduler.start
|
13
12
|
end
|
14
13
|
module_function :scheduler
|
15
14
|
|
16
|
-
# call-seq:
|
17
|
-
# Procrastinate.proxy(obj) => proxy
|
18
|
-
#
|
19
15
|
# Creates a proxy that will execute methods called on obj in a child process.
|
20
16
|
#
|
21
|
-
#
|
22
|
-
#
|
17
|
+
# @example
|
23
18
|
# proxy = Procrastinate.proxy("foo")
|
24
19
|
# r = proxy += "bar"
|
25
20
|
# r.value # => 'foobar'
|
26
21
|
#
|
22
|
+
# @param obj [Object] Ruby object that the calls need to be proxied to
|
23
|
+
# @return [Proxy] proxy object that will execute method calls in child
|
24
|
+
# processes
|
25
|
+
#
|
27
26
|
def proxy(obj)
|
28
27
|
scheduler.proxy(obj)
|
29
28
|
end
|
30
29
|
module_function :proxy
|
31
30
|
|
32
|
-
# call-seq:
|
33
|
-
# Procrastinate.schedule { some_work }
|
34
|
-
#
|
35
31
|
# Schedules a block to be executed in its own thread. Returns the future that
|
36
32
|
# will return the blocks return value.
|
37
33
|
#
|
34
|
+
# @example
|
35
|
+
# r = Procrastinate.schedule { do_some_work }
|
36
|
+
# r.value # => the blocks return value
|
37
|
+
#
|
38
|
+
# @param block [Proc] block that will be executed in a child process
|
39
|
+
# @return [Task::Result] a promise for the blocks return value
|
40
|
+
#
|
38
41
|
def schedule(&block)
|
39
42
|
scheduler.schedule(&block)
|
40
43
|
end
|
41
44
|
module_function :schedule
|
42
45
|
|
43
|
-
# call-seq:
|
44
|
-
# Procrastinate.join
|
45
|
-
#
|
46
46
|
# Waits for all currently scheduled tasks to complete. This is like calling
|
47
47
|
# #value on all result objects, except that nothing is returned.
|
48
48
|
#
|
49
|
-
#
|
50
|
-
#
|
49
|
+
# @example
|
51
50
|
# proxy = Procrastinate.proxy("foo")
|
52
51
|
# r = proxy += "bar"
|
53
52
|
# Procrastinate.join
|
54
53
|
# r.ready? # => true
|
55
54
|
#
|
55
|
+
# @return [void]
|
56
|
+
#
|
56
57
|
def join
|
57
58
|
scheduler.join
|
58
59
|
end
|
@@ -62,6 +63,8 @@ module Procrastinate
|
|
62
63
|
# since it consumes almost no resources when not active. This is mainly
|
63
64
|
# useful in tests to achieve isolation.
|
64
65
|
#
|
66
|
+
# @private
|
67
|
+
#
|
65
68
|
def shutdown
|
66
69
|
scheduler.shutdown
|
67
70
|
end
|
@@ -166,13 +166,18 @@ class Procrastinate::ProcessManager
|
|
166
166
|
# Ignore: This means that no childs remain.
|
167
167
|
end
|
168
168
|
|
169
|
-
# Spawns a process to work on +task+. If a block is given, it is called
|
170
|
-
#
|
169
|
+
# Spawns a process to work on +task+. If a block is given, it is called when
|
170
|
+
# the task completes. This method should only be called from a strategy
|
171
171
|
# inside the dispatchers thread. Otherwise it will expose threading issues.
|
172
172
|
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
173
|
+
# @example
|
174
|
+
# create_process(wi) { puts "Task is complete" }
|
175
|
+
#
|
176
|
+
# @param task [Procrastinate::Task::Callable] task to be run inside the
|
177
|
+
# forked process
|
178
|
+
# @param completion_handler [Proc] completion handler that is called when
|
179
|
+
# the process exits
|
180
|
+
# @return [void]
|
176
181
|
#
|
177
182
|
def create_process(task, &completion_handler)
|
178
183
|
# Tasks that are interested in getting messages from their childs must
|
@@ -224,4 +229,14 @@ class Procrastinate::ProcessManager
|
|
224
229
|
finalize_children
|
225
230
|
end
|
226
231
|
end
|
232
|
+
|
233
|
+
# Kills all running processes by sending them a QUIT signal.
|
234
|
+
#
|
235
|
+
# @param signal [String] signal to send to the forked processes.
|
236
|
+
#
|
237
|
+
def kill_processes(signal='QUIT')
|
238
|
+
children.each do |pid, process|
|
239
|
+
Process.kill(signal, pid)
|
240
|
+
end
|
241
|
+
end
|
227
242
|
end
|
@@ -3,16 +3,41 @@ require 'thread'
|
|
3
3
|
|
4
4
|
# API Frontend for the procrastinate library. Allows scheduling of tasks and
|
5
5
|
# workers in seperate processes and provides minimal locking primitives.
|
6
|
+
#
|
7
|
+
# == Synopsis
|
8
|
+
# scheduler = Procrastinate::Scheduler.start
|
9
|
+
#
|
10
|
+
# Schedule a block to run in its own process:
|
11
|
+
# result = scheduler.schedule { Process.pid }
|
12
|
+
# result.value # => child process pid
|
6
13
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
14
|
+
# Or schedule a message call to an object to be run in another process:
|
15
|
+
# proxy = scheduler.proxy(1)
|
16
|
+
# result = proxy + 2
|
17
|
+
# result.value # => 3
|
18
|
+
#
|
19
|
+
# You can ask the result value if it is ready yet:
|
20
|
+
# result.ready? # true/false
|
21
|
+
#
|
22
|
+
# Stop the scheduler, waiting for all scheduled work to finish:
|
23
|
+
# scheduler.shutdown
|
24
|
+
#
|
25
|
+
# Or shutting down hard, doesn't wait for work to finish:
|
26
|
+
# scheduler.shutting(true)
|
27
|
+
#
|
28
|
+
# @note Each scheduler owns its own thread that does all the processing. The
|
29
|
+
# interface between your main thread and the procrastinate thread is defined
|
30
|
+
# in this class.
|
10
31
|
#
|
11
32
|
class Procrastinate::Scheduler
|
33
|
+
# Process manager associated with this scheduler
|
12
34
|
attr_reader :manager
|
35
|
+
# Schedule strategy associated with this scheduler
|
13
36
|
attr_reader :strategy
|
14
|
-
|
37
|
+
# Task queue
|
38
|
+
attr_reader :task_producer
|
15
39
|
|
40
|
+
# @see Scheduler.start
|
16
41
|
def initialize(strategy)
|
17
42
|
@strategy = strategy || Procrastinate::SpawnStrategy::Default.new
|
18
43
|
@manager = Procrastinate::ProcessManager.new
|
@@ -20,11 +45,18 @@ class Procrastinate::Scheduler
|
|
20
45
|
# State takes three values: :running, :soft_shutdown, :real_shutdown
|
21
46
|
# :soft_shutdown will not accept any new tasks and wait for completion
|
22
47
|
# :real_shutdown will stop as soon as possible (still closing down nicely)
|
23
|
-
@state
|
24
|
-
|
48
|
+
@state = :running
|
49
|
+
|
50
|
+
# If we're used in server mode, this will be replaced with a task producer
|
51
|
+
# that produces new worker processes.
|
52
|
+
@task_producer = Queue.new
|
25
53
|
end
|
26
54
|
|
27
|
-
# Starts a new scheduler
|
55
|
+
# Starts a new scheduler.
|
56
|
+
#
|
57
|
+
# @param strategy [SpawnStrategy] strategy to use when spawning new processes.
|
58
|
+
# Will default to {SpawnStrategy::Default}.
|
59
|
+
# @return [Scheduler]
|
28
60
|
#
|
29
61
|
def self.start(strategy=nil)
|
30
62
|
new(strategy).
|
@@ -37,11 +69,13 @@ class Procrastinate::Scheduler
|
|
37
69
|
# Returns a proxy for the +worker+ instance that will allow executing its
|
38
70
|
# methods in a new process.
|
39
71
|
#
|
40
|
-
#
|
41
|
-
#
|
72
|
+
# @example
|
42
73
|
# proxy = scheduler.proxy(worker)
|
43
74
|
# status = proxy.do_some_work # will execute later and in its own process
|
44
75
|
#
|
76
|
+
# @param worker [Object] Ruby object that executes the work
|
77
|
+
# @return [Proxy]
|
78
|
+
#
|
45
79
|
def proxy(worker)
|
46
80
|
return Procrastinate::Proxy.new(worker, self)
|
47
81
|
end
|
@@ -50,6 +84,8 @@ class Procrastinate::Scheduler
|
|
50
84
|
# used inside task execution processes; If you call it from your main
|
51
85
|
# process, the result is undefined.
|
52
86
|
#
|
87
|
+
# @return [Runtime]
|
88
|
+
#
|
53
89
|
def runtime
|
54
90
|
Procrastinate::Runtime.new
|
55
91
|
end
|
@@ -57,6 +93,16 @@ class Procrastinate::Scheduler
|
|
57
93
|
# Called by the proxy to schedule work. You can implement your own Task
|
58
94
|
# classes; the relevant interface consists of only a #run method.
|
59
95
|
#
|
96
|
+
# @overload schedule(task=nil)
|
97
|
+
# Runs task in its own worker process.
|
98
|
+
# @param task [#run] task to be run in its own worker process
|
99
|
+
# @return [Task::Result]
|
100
|
+
#
|
101
|
+
# @overload schedule(&block)
|
102
|
+
# Executes the Ruby block in its own worker process.
|
103
|
+
# @param block [Proc] block to be executed in worker process
|
104
|
+
# @return [Task::Result]
|
105
|
+
#
|
60
106
|
def schedule(task=nil, &block)
|
61
107
|
fail "Shutting down..." if @state != :running
|
62
108
|
|
@@ -67,7 +113,7 @@ class Procrastinate::Scheduler
|
|
67
113
|
task = Procrastinate::Task::Callable.new(block)
|
68
114
|
end
|
69
115
|
|
70
|
-
|
116
|
+
task_producer << task
|
71
117
|
|
72
118
|
# Create an occasion for spawning
|
73
119
|
manager.wakeup
|
@@ -87,7 +133,7 @@ class Procrastinate::Scheduler
|
|
87
133
|
# Wait until all tasks are done.
|
88
134
|
loop do
|
89
135
|
manager.wakeup
|
90
|
-
break if
|
136
|
+
break if task_producer.empty? && manager.process_count==0
|
91
137
|
sleep 0.01
|
92
138
|
end
|
93
139
|
|
@@ -115,8 +161,8 @@ private
|
|
115
161
|
# *control thread*
|
116
162
|
#
|
117
163
|
def spawn
|
118
|
-
while strategy.should_spawn? && !
|
119
|
-
task =
|
164
|
+
while strategy.should_spawn? && !task_producer.empty?
|
165
|
+
task = task_producer.pop
|
120
166
|
strategy.notify_spawn
|
121
167
|
manager.create_process(task) do
|
122
168
|
strategy.notify_dead
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Procrastinate
|
2
|
+
class Server
|
3
|
+
def initialize
|
4
|
+
@manager = Procrastinate::ProcessManager.new
|
5
|
+
@state = :new
|
6
|
+
end
|
7
|
+
|
8
|
+
def start(n, activity_check_interval=nil, &block)
|
9
|
+
fail "Already running server." unless @state == :new
|
10
|
+
|
11
|
+
@block = block
|
12
|
+
@strategy = Procrastinate::SpawnStrategy::Throttled.new(n)
|
13
|
+
@state = :running
|
14
|
+
@check_interval = activity_check_interval
|
15
|
+
|
16
|
+
start_thread
|
17
|
+
end
|
18
|
+
|
19
|
+
def shutdown
|
20
|
+
fail "For shutdown, server must be running." unless @state == :running
|
21
|
+
|
22
|
+
@state = :shutdown
|
23
|
+
@manager.wakeup
|
24
|
+
|
25
|
+
@thread.join if @thread
|
26
|
+
|
27
|
+
@thread = nil
|
28
|
+
@state = :new
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def start_thread
|
33
|
+
@thread = Thread.start(&method(:control_thread_main))
|
34
|
+
end
|
35
|
+
|
36
|
+
# @note This method runs in the control thread only.
|
37
|
+
#
|
38
|
+
def spawn_new_workers
|
39
|
+
while @strategy.should_spawn?
|
40
|
+
task = Procrastinate::Task::Callable.new(@block)
|
41
|
+
|
42
|
+
@strategy.notify_spawn
|
43
|
+
@manager.create_process(task) do
|
44
|
+
@strategy.notify_dead
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @note This method runs in the control thread only.
|
50
|
+
#
|
51
|
+
def control_thread_main
|
52
|
+
# Start managers work
|
53
|
+
@manager.setup
|
54
|
+
|
55
|
+
# Loop until someone requests a shutdown.
|
56
|
+
loop do
|
57
|
+
spawn_new_workers
|
58
|
+
|
59
|
+
@manager.step
|
60
|
+
|
61
|
+
break if @state == :shutdown
|
62
|
+
end
|
63
|
+
|
64
|
+
@manager.kill_processes
|
65
|
+
@manager.teardown
|
66
|
+
rescue => ex
|
67
|
+
# Sometimes exceptions vanish silently. This will avoid that, even though
|
68
|
+
# they should abort the whole process.
|
69
|
+
|
70
|
+
warn "Exception #{ex.inspect} caught."
|
71
|
+
ex.backtrace.first(5).each do |line|
|
72
|
+
warn line
|
73
|
+
end
|
74
|
+
|
75
|
+
raise
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: procrastinate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,85 +10,136 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-12-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: state_machine
|
17
|
-
|
18
|
-
|
17
|
+
prerelease: false
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: '1.1'
|
23
|
+
none: false
|
23
24
|
type: :runtime
|
24
|
-
|
25
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
none: false
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: cod
|
28
|
-
|
29
|
-
|
33
|
+
prerelease: false
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
30
35
|
requirements:
|
31
36
|
- - ~>
|
32
37
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
38
|
+
version: '0.5'
|
39
|
+
none: false
|
34
40
|
type: :runtime
|
35
|
-
|
36
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.5'
|
46
|
+
none: false
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: rake
|
39
|
-
|
40
|
-
|
49
|
+
prerelease: false
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
41
51
|
requirements:
|
42
52
|
- - ! '>='
|
43
53
|
- !ruby/object:Gem::Version
|
44
54
|
version: '0'
|
55
|
+
none: false
|
45
56
|
type: :development
|
46
|
-
|
47
|
-
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
none: false
|
48
63
|
- !ruby/object:Gem::Dependency
|
49
64
|
name: rspec
|
50
|
-
|
51
|
-
|
65
|
+
prerelease: false
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
52
67
|
requirements:
|
53
68
|
- - ! '>='
|
54
69
|
- !ruby/object:Gem::Version
|
55
70
|
version: '0'
|
71
|
+
none: false
|
56
72
|
type: :development
|
57
|
-
|
58
|
-
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
none: false
|
59
79
|
- !ruby/object:Gem::Dependency
|
60
80
|
name: flexmock
|
61
|
-
|
62
|
-
|
81
|
+
prerelease: false
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
63
83
|
requirements:
|
64
84
|
- - ! '>='
|
65
85
|
- !ruby/object:Gem::Version
|
66
86
|
version: '0'
|
87
|
+
none: false
|
67
88
|
type: :development
|
68
|
-
|
69
|
-
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
none: false
|
70
95
|
- !ruby/object:Gem::Dependency
|
71
96
|
name: guard
|
72
|
-
|
73
|
-
|
97
|
+
prerelease: false
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
74
99
|
requirements:
|
75
100
|
- - ! '>='
|
76
101
|
- !ruby/object:Gem::Version
|
77
102
|
version: '0'
|
103
|
+
none: false
|
78
104
|
type: :development
|
79
|
-
|
80
|
-
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
none: false
|
81
111
|
- !ruby/object:Gem::Dependency
|
82
112
|
name: growl
|
83
|
-
|
84
|
-
|
113
|
+
prerelease: false
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
85
115
|
requirements:
|
86
116
|
- - ! '>='
|
87
117
|
- !ruby/object:Gem::Version
|
88
118
|
version: '0'
|
119
|
+
none: false
|
89
120
|
type: :development
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
none: false
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: yard
|
90
129
|
prerelease: false
|
91
|
-
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
none: false
|
136
|
+
type: :development
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
none: false
|
92
143
|
description:
|
93
144
|
email:
|
94
145
|
- kaspar.schiess@absurd.li
|
@@ -109,6 +160,7 @@ files:
|
|
109
160
|
- lib/procrastinate/proxy.rb
|
110
161
|
- lib/procrastinate/runtime.rb
|
111
162
|
- lib/procrastinate/scheduler.rb
|
163
|
+
- lib/procrastinate/server.rb
|
112
164
|
- lib/procrastinate/spawn_strategy/default.rb
|
113
165
|
- lib/procrastinate/spawn_strategy/simple.rb
|
114
166
|
- lib/procrastinate/spawn_strategy/throttled.rb
|
@@ -122,6 +174,7 @@ files:
|
|
122
174
|
- lib/procrastinate.rb
|
123
175
|
- examples/locking.rb
|
124
176
|
- examples/pascal.rb
|
177
|
+
- examples/server.rb
|
125
178
|
- examples/simple.rb
|
126
179
|
- examples/throttled.rb
|
127
180
|
homepage: http://github.com/kschiess/procrastinate
|
@@ -133,27 +186,22 @@ rdoc_options:
|
|
133
186
|
require_paths:
|
134
187
|
- lib
|
135
188
|
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
-
none: false
|
137
189
|
requirements:
|
138
190
|
- - ! '>='
|
139
191
|
- !ruby/object:Gem::Version
|
140
192
|
version: '0'
|
141
|
-
segments:
|
142
|
-
- 0
|
143
|
-
hash: 3407763989240963082
|
144
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
193
|
none: false
|
194
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
195
|
requirements:
|
147
196
|
- - ! '>='
|
148
197
|
- !ruby/object:Gem::Version
|
149
198
|
version: '0'
|
150
|
-
|
151
|
-
- 0
|
152
|
-
hash: 3407763989240963082
|
199
|
+
none: false
|
153
200
|
requirements: []
|
154
201
|
rubyforge_project:
|
155
|
-
rubygems_version: 1.8.
|
202
|
+
rubygems_version: 1.8.24
|
156
203
|
signing_key:
|
157
204
|
specification_version: 3
|
158
205
|
summary: Framework to run tasks in separate processes.
|
159
206
|
test_files: []
|
207
|
+
has_rdoc:
|