zoidberg 0.0.1 → 0.1.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 +4 -4
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +25 -0
- data/LICENSE +13 -0
- data/README.md +151 -0
- data/lib/zoidberg/future.rb +34 -0
- data/lib/zoidberg/logger.rb +23 -0
- data/lib/zoidberg/pool.rb +100 -0
- data/lib/zoidberg/proxy/confined.rb +175 -0
- data/lib/zoidberg/proxy/liberated.rb +135 -0
- data/lib/zoidberg/proxy.rb +211 -0
- data/lib/zoidberg/registry.rb +7 -0
- data/lib/zoidberg/shell.rb +354 -0
- data/lib/zoidberg/signal.rb +109 -0
- data/lib/zoidberg/supervise.rb +41 -0
- data/lib/zoidberg/supervisor.rb +82 -0
- data/lib/zoidberg/task.rb +147 -0
- data/lib/zoidberg/timer.rb +230 -0
- data/lib/zoidberg/version.rb +2 -1
- data/lib/zoidberg/weak_ref.rb +51 -0
- data/lib/zoidberg.rb +55 -0
- data/zoidberg.gemspec +1 -0
- metadata +31 -2
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'zoidberg'
|
2
|
+
|
3
|
+
module Zoidberg
|
4
|
+
class Supervisor
|
5
|
+
|
6
|
+
include Zoidberg::Shell
|
7
|
+
|
8
|
+
# @return [Registry] current supervision registry
|
9
|
+
attr_reader :registry
|
10
|
+
|
11
|
+
# Create a new supervisor
|
12
|
+
#
|
13
|
+
# @return [self]
|
14
|
+
def initialize
|
15
|
+
@registry = Registry.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# Fetch the supervised instance or pool
|
19
|
+
#
|
20
|
+
# @param k [String, Symbol] name of supervised item
|
21
|
+
# @return [Object] supervised object
|
22
|
+
def [](k)
|
23
|
+
registry[k]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Supervise an instance
|
27
|
+
#
|
28
|
+
# @param name [String, Symbol] name of item to supervise
|
29
|
+
# @param klass [Class] class of instance
|
30
|
+
# @param args [Object] initialization arguments
|
31
|
+
# @yieldblock initialization block
|
32
|
+
# @return [Object] new instance
|
33
|
+
def supervise_as(name, klass, *args, &block)
|
34
|
+
klass = supervised_class(klass)
|
35
|
+
registry[name] = klass.new(*args, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Supervise a pool
|
39
|
+
#
|
40
|
+
# @param klass [Class] class of instance
|
41
|
+
# @param args [Hash] initialization arguments
|
42
|
+
# @option args [String] :as name of pool
|
43
|
+
# @option args [Integer] :size size of pool
|
44
|
+
# @option args [Array<Object>] :args initialization arguments
|
45
|
+
# @yieldblock initialization block
|
46
|
+
# @return [Object] new pool
|
47
|
+
def pool(klass, args={}, &block)
|
48
|
+
name = args[:as]
|
49
|
+
size = args[:size].to_i
|
50
|
+
args = args.fetch(:args, [])
|
51
|
+
klass = supervised_class(klass)
|
52
|
+
s_pool = Pool.new(klass, *args, &block)
|
53
|
+
s_pool._worker_count(size > 0 ? size : 1)
|
54
|
+
registry[name] = s_pool
|
55
|
+
end
|
56
|
+
|
57
|
+
# Destroy all supervised instances prior to destruction
|
58
|
+
def terminate
|
59
|
+
registry.values.each do |item|
|
60
|
+
item._zoidberg_destroy!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Make a supervised class
|
67
|
+
#
|
68
|
+
# @param klass [Class]
|
69
|
+
# @return [Class]
|
70
|
+
def supervised_class(klass)
|
71
|
+
unless(klass.include?(Zoidberg::Supervise))
|
72
|
+
n_klass = Class.new(klass) do
|
73
|
+
include Zoidberg::Supervise
|
74
|
+
end
|
75
|
+
n_klass.class_eval("def self.name; '#{klass.name}'; end")
|
76
|
+
klass = n_klass
|
77
|
+
end
|
78
|
+
klass
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'zoidberg'
|
2
|
+
|
3
|
+
module Zoidberg
|
4
|
+
|
5
|
+
# Run a task
|
6
|
+
class Task
|
7
|
+
|
8
|
+
# Supported task styles
|
9
|
+
SUPPORTED_STYLES = [:serial, :async]
|
10
|
+
|
11
|
+
# @return [Symbol] :fiber or :thread
|
12
|
+
attr_reader :style
|
13
|
+
# @return [Object] originator of task
|
14
|
+
attr_reader :origin
|
15
|
+
# @return [Proc] block to execute
|
16
|
+
attr_reader :content
|
17
|
+
attr_reader :content_arguments
|
18
|
+
# @return [Thread, Fiber] underlying task container
|
19
|
+
attr_reader :task
|
20
|
+
|
21
|
+
# Create a new task
|
22
|
+
#
|
23
|
+
# @param task_style [Symbol]
|
24
|
+
# @param origin [Object] origin object of block
|
25
|
+
# @yield block to execute
|
26
|
+
# @return [self]
|
27
|
+
def initialize(task_style, origin, block_args=[], &block)
|
28
|
+
unless(SUPPORTED_STYLES.include?(task_style))
|
29
|
+
raise ArgumentError.new("Allowed style values: #{SUPPORTED_STYLES.map(&:inspect).join(', ')} but received: #{task_style.inspect}")
|
30
|
+
end
|
31
|
+
@style = task_style
|
32
|
+
@origin = origin
|
33
|
+
@content = block
|
34
|
+
@content_arguments = block_args
|
35
|
+
@result = nil
|
36
|
+
send("run_#{style}")
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Object] result of task
|
40
|
+
def value
|
41
|
+
if(task.alive?)
|
42
|
+
@result = style == :async ? task.join : task.resume
|
43
|
+
end
|
44
|
+
@result
|
45
|
+
end
|
46
|
+
|
47
|
+
# Force task to stop prior to completion if still in running state
|
48
|
+
#
|
49
|
+
# @return [NilClass]
|
50
|
+
def halt!
|
51
|
+
if(style == :async)
|
52
|
+
task.kill
|
53
|
+
else
|
54
|
+
@task = nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [TrueClass, FalseClass] task currently waiting to run
|
59
|
+
def waiting?
|
60
|
+
task && task.alive? && task.respond_to?(:stop?) ? task.stop? : true
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [TrueClass, FalseClass] task is running
|
64
|
+
def running?
|
65
|
+
if(task)
|
66
|
+
style == :async && task.alive? && !task.stop?
|
67
|
+
else
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [TrueClass, FalseClass] task is complete
|
73
|
+
def complete?
|
74
|
+
task.nil? || !task.alive?
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [TrueClass, FalseClass] task complete in error state
|
78
|
+
def error?
|
79
|
+
complete? && value.is_a?(Exception)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [TrueClass, FalseClass] task complete in success state
|
83
|
+
def success?
|
84
|
+
complete? && !error?
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reliquish running state and return optional value(s)
|
88
|
+
#
|
89
|
+
# @param args [Object] values to return
|
90
|
+
# @return [Object, Array<Object>]
|
91
|
+
def cease(*args)
|
92
|
+
if(style == :async)
|
93
|
+
task[:task_args] = args
|
94
|
+
task.stop
|
95
|
+
task[:task_args]
|
96
|
+
else
|
97
|
+
Fiber.yield(*args)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Regain running state with optional value(s)
|
102
|
+
# @param args [Object] values to provide
|
103
|
+
# @return [Object, Array<Object>]
|
104
|
+
def proceed(*args)
|
105
|
+
if(style == :serial)
|
106
|
+
task.resume(*args)
|
107
|
+
else
|
108
|
+
task[:task_args] = args
|
109
|
+
task.run
|
110
|
+
task[:task_args]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
# Create new fiber based task
|
117
|
+
#
|
118
|
+
# @return [Fiber]
|
119
|
+
def run_serial
|
120
|
+
@task = Fiber.new do
|
121
|
+
begin
|
122
|
+
self.instance_exec(*content_arguments, &content)
|
123
|
+
rescue Exception => e
|
124
|
+
origin.send(:raise, e)
|
125
|
+
raise
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Create new thread based task
|
131
|
+
#
|
132
|
+
# @return [Thread]
|
133
|
+
def run_async
|
134
|
+
@task = Thread.new do
|
135
|
+
Thread.stop
|
136
|
+
begin
|
137
|
+
self.instance_exec(*content_arguments, &content)
|
138
|
+
rescue Exception => e
|
139
|
+
origin.send(:raise, e)
|
140
|
+
raise
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'zoidberg'
|
2
|
+
|
3
|
+
module Zoidberg
|
4
|
+
|
5
|
+
# Simple timer class
|
6
|
+
class Timer
|
7
|
+
|
8
|
+
class Action
|
9
|
+
|
10
|
+
# @return [TrueClass, FalseClass]
|
11
|
+
attr_reader :recur
|
12
|
+
# @return [Proc] action to run
|
13
|
+
attr_reader :action
|
14
|
+
# @return [Numeric]
|
15
|
+
attr_reader :interval
|
16
|
+
# @return [Float]
|
17
|
+
attr_reader :last_run
|
18
|
+
|
19
|
+
# Create a new action
|
20
|
+
#
|
21
|
+
# @param args [Hash]
|
22
|
+
# @option args [Numeric] :interval
|
23
|
+
# @option args [TrueClass, FalseClass] :recur
|
24
|
+
# @return [self]
|
25
|
+
def initialize(args={}, &block)
|
26
|
+
unless(block)
|
27
|
+
raise ArgumentError.new 'Action is required. Block must be provided!'
|
28
|
+
end
|
29
|
+
@action = block
|
30
|
+
@recur = args.fetch(:recur, false)
|
31
|
+
@interval = args.fetch(:interval, 5)
|
32
|
+
@last_run = Time.now.to_f
|
33
|
+
@cancel = false
|
34
|
+
end
|
35
|
+
|
36
|
+
# Cancel the action
|
37
|
+
#
|
38
|
+
# @return [TrueClass]
|
39
|
+
def cancel
|
40
|
+
@recur = false
|
41
|
+
@cancel = true
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [TrueClass, FalseClass]
|
45
|
+
def cancelled?
|
46
|
+
@cancel
|
47
|
+
end
|
48
|
+
|
49
|
+
# Run the action
|
50
|
+
#
|
51
|
+
# @return [self]
|
52
|
+
def run!
|
53
|
+
@last_run = Time.now.to_f
|
54
|
+
action.call
|
55
|
+
@last_run = Time.now.to_f
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
include Zoidberg::SoftShell
|
62
|
+
|
63
|
+
# Custom exception used to wakeup timer
|
64
|
+
class Wakeup < StandardError; end
|
65
|
+
|
66
|
+
# @return [Mutex]
|
67
|
+
attr_reader :notify_locker
|
68
|
+
# @return [Array<Action>] items to run
|
69
|
+
attr_reader :to_run
|
70
|
+
# @return [TrueClass, FalseClass] timer is paused
|
71
|
+
attr_reader :paused
|
72
|
+
|
73
|
+
# Create a new timer
|
74
|
+
#
|
75
|
+
# @return [self]
|
76
|
+
def initialize
|
77
|
+
@to_run = []
|
78
|
+
@notify_locker = Mutex.new
|
79
|
+
@paused = false
|
80
|
+
@thread = Thread.new{ run! }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Run recurring action at given interval
|
84
|
+
#
|
85
|
+
# @param interval [Numeric]
|
86
|
+
# @yield action to run
|
87
|
+
# @return [Action]
|
88
|
+
def every(interval, &block)
|
89
|
+
action = Action.new({
|
90
|
+
:interval => interval,
|
91
|
+
:recur => true
|
92
|
+
},
|
93
|
+
&block
|
94
|
+
)
|
95
|
+
to_run.push(action)
|
96
|
+
reset
|
97
|
+
action
|
98
|
+
end
|
99
|
+
|
100
|
+
# Run action after given interval
|
101
|
+
#
|
102
|
+
# @param interval [Numeric]
|
103
|
+
# @yield action to run
|
104
|
+
# @return [Action]
|
105
|
+
def after(interval, &block)
|
106
|
+
action = Action.new(
|
107
|
+
{:interval => interval},
|
108
|
+
&block
|
109
|
+
)
|
110
|
+
to_run.push(action)
|
111
|
+
reset
|
112
|
+
action
|
113
|
+
end
|
114
|
+
|
115
|
+
# Pause the timer to prevent any actions from being run
|
116
|
+
#
|
117
|
+
# @return [self]
|
118
|
+
def pause
|
119
|
+
unless(@paused)
|
120
|
+
@paused = true
|
121
|
+
reset
|
122
|
+
end
|
123
|
+
current_self
|
124
|
+
end
|
125
|
+
|
126
|
+
# Resume a paused timer
|
127
|
+
#
|
128
|
+
# @return [self]
|
129
|
+
def resume
|
130
|
+
if(@paused)
|
131
|
+
@paused = false
|
132
|
+
reset
|
133
|
+
end
|
134
|
+
current_self
|
135
|
+
end
|
136
|
+
|
137
|
+
# Remove all actions from the timer
|
138
|
+
#
|
139
|
+
# @return [self]
|
140
|
+
def cancel
|
141
|
+
to_run.clear
|
142
|
+
reset
|
143
|
+
current_self
|
144
|
+
end
|
145
|
+
|
146
|
+
# Reset the timer
|
147
|
+
#
|
148
|
+
# @param wakeup [TrueClass, FalseClass] wakeup the timer thread
|
149
|
+
# @return [self]
|
150
|
+
def reset(wakeup=true)
|
151
|
+
if(wakeup)
|
152
|
+
notify_locker.synchronize do
|
153
|
+
to_run.sort_by! do |item|
|
154
|
+
(item.interval + item.last_run) - Time.now.to_f
|
155
|
+
end
|
156
|
+
@thread.raise Wakeup.new
|
157
|
+
end
|
158
|
+
else
|
159
|
+
to_run.sort_by! do |item|
|
160
|
+
(item.interval + item.last_run) - Time.now.to_f
|
161
|
+
end
|
162
|
+
end
|
163
|
+
current_self
|
164
|
+
end
|
165
|
+
|
166
|
+
# @return [Numeric, NilClass] interval to next action
|
167
|
+
def next_interval
|
168
|
+
unless(to_run.empty? || paused)
|
169
|
+
item = to_run.first
|
170
|
+
result = (item.last_run + item.interval) - Time.now.to_f
|
171
|
+
result < 0 ? 0 : result
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Run any actions that are ready
|
176
|
+
#
|
177
|
+
# @return [self]
|
178
|
+
def run_ready
|
179
|
+
items = to_run.find_all do |item|
|
180
|
+
((item.interval + item.last_run) - Time.now.to_f) <= 0
|
181
|
+
end
|
182
|
+
to_run.delete_if do |item|
|
183
|
+
items.include?(item)
|
184
|
+
end
|
185
|
+
items.map do |item|
|
186
|
+
begin
|
187
|
+
item.run! unless item.cancelled?
|
188
|
+
rescue DeadException
|
189
|
+
item.cancel
|
190
|
+
rescue => e
|
191
|
+
Zoidberg.logger.error "<#{self}> Timed action generated an error: #{e.class.name} - #{e}"
|
192
|
+
end
|
193
|
+
item if item.recur
|
194
|
+
end.compact.each do |item|
|
195
|
+
to_run << item
|
196
|
+
end
|
197
|
+
current_self
|
198
|
+
end
|
199
|
+
|
200
|
+
protected
|
201
|
+
|
202
|
+
# Run the timer loop
|
203
|
+
def run!
|
204
|
+
loop do
|
205
|
+
begin
|
206
|
+
interval = nil
|
207
|
+
# TODO: update with select for better subsecond support
|
208
|
+
notify_locker.synchronize do
|
209
|
+
interval = next_interval
|
210
|
+
end
|
211
|
+
sleep interval
|
212
|
+
notify_locker.synchronize do
|
213
|
+
run_ready
|
214
|
+
reset(false)
|
215
|
+
end
|
216
|
+
rescue Wakeup
|
217
|
+
Zoidberg.logger.debug "<#{self}> Received wakeup notification. Rechecking sleep interval!"
|
218
|
+
rescue DeadException
|
219
|
+
raise
|
220
|
+
rescue => e
|
221
|
+
Zoidberg.logger.error "<#{self}> Unexpected error in runner: #{e.class.name} - #{e}"
|
222
|
+
Zoidberg.logger.debug "<#{self}> #{e.class.name}: #{e}\n#{e.backtrace.join("\n")}"
|
223
|
+
current_self.raise e
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
data/lib/zoidberg/version.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'zoidberg'
|
2
|
+
|
3
|
+
module Zoidberg
|
4
|
+
# Provide weak reference to object allowing for it to be garbage
|
5
|
+
# collected. This is a stripped down version of the ::WeakRef class
|
6
|
+
class WeakRef < BasicObject
|
7
|
+
|
8
|
+
# Exception type raised when referenced object no longer exists
|
9
|
+
class RecycledException < ::RuntimeError
|
10
|
+
# @return [String] ID of referenced object casted to string
|
11
|
+
attr_reader :recycled_object_id
|
12
|
+
# Create a new exception instance
|
13
|
+
#
|
14
|
+
# @param msg [String] exception message
|
15
|
+
# @param recycled_object_id [String] casted object ID
|
16
|
+
# @return [self]
|
17
|
+
def initialize(msg, recycled_object_id)
|
18
|
+
@recycled_object_id = recycled_object_id
|
19
|
+
super(msg)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@@__zoidberg_map = ::ObjectSpace::WeakMap.new
|
24
|
+
|
25
|
+
# Create a new weak reference
|
26
|
+
#
|
27
|
+
# @param orig [Object] referenced object
|
28
|
+
# @return [self]
|
29
|
+
def initialize(orig)
|
30
|
+
@_key = orig.object_id.to_s
|
31
|
+
@@__zoidberg_map[@_key] = orig
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(*args, &block) # :nodoc:
|
35
|
+
if(@@__zoidberg_map[@_key])
|
36
|
+
@@__zoidberg_map[@_key].__send__(*args, &block)
|
37
|
+
else
|
38
|
+
::Kernel.raise RecycledException.new('Instance has been recycled by the system!', @_key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# jruby compat [https://github.com/jruby/jruby/pull/2520]
|
47
|
+
if(Zoidberg::WeakRef.instance_methods.include?(:object_id))
|
48
|
+
class Zoidberg::WeakRef
|
49
|
+
undef_method :object_id
|
50
|
+
end
|
51
|
+
end
|
data/lib/zoidberg.rb
CHANGED
@@ -1 +1,56 @@
|
|
1
|
+
require 'bogo'
|
2
|
+
require 'thread'
|
3
|
+
require 'securerandom'
|
1
4
|
require 'zoidberg/version'
|
5
|
+
|
6
|
+
# Why not Zoidberg!?
|
7
|
+
module Zoidberg
|
8
|
+
autoload :DeadException, 'zoidberg/shell'
|
9
|
+
autoload :Future, 'zoidberg/future'
|
10
|
+
autoload :Logger, 'zoidberg/logger'
|
11
|
+
autoload :Pool, 'zoidberg/pool'
|
12
|
+
autoload :Proxy, 'zoidberg/proxy'
|
13
|
+
autoload :Registry, 'zoidberg/registry'
|
14
|
+
autoload :Shell, 'zoidberg/shell'
|
15
|
+
autoload :SoftShell, 'zoidberg/shell'
|
16
|
+
autoload :HardShell, 'zoidberg/shell'
|
17
|
+
autoload :Signal, 'zoidberg/signal'
|
18
|
+
autoload :Supervise, 'zoidberg/supervise'
|
19
|
+
autoload :Supervisor, 'zoidberg/supervisor'
|
20
|
+
autoload :Task, 'zoidberg/task'
|
21
|
+
autoload :Timer, 'zoidberg/timer'
|
22
|
+
autoload :WeakRef, 'zoidberg/weak_ref'
|
23
|
+
|
24
|
+
class << self
|
25
|
+
|
26
|
+
attr_accessor :default_shell
|
27
|
+
|
28
|
+
# @return [Zoidberg::Logger]
|
29
|
+
def logger
|
30
|
+
@zoidberg_logger
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set new default logger
|
34
|
+
#
|
35
|
+
# @param log [Zoidberg::Logger]
|
36
|
+
# @return [zoidberg::Logger]
|
37
|
+
def logger=(log)
|
38
|
+
unless(log.is_a?(Zoidberg::Logger))
|
39
|
+
raise TypeError.new "Expecting type `Zoidberg::Logger` but received type `#{log.class}`"
|
40
|
+
end
|
41
|
+
@zoidberg_logger = log
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String] UUID
|
45
|
+
def uuid
|
46
|
+
SecureRandom.uuid
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# Always enable default logger
|
54
|
+
Zoidberg.logger = Zoidberg::Logger.new(STDERR)
|
55
|
+
# Set default shell to soft shell
|
56
|
+
Zoidberg.default_shell = Zoidberg::SoftShell
|
data/zoidberg.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.require_path = 'lib'
|
12
12
|
s.license = 'Apache 2.0'
|
13
13
|
s.add_runtime_dependency 'bogo'
|
14
|
+
s.add_runtime_dependency 'mono_logger'
|
14
15
|
s.add_development_dependency 'pry'
|
15
16
|
s.add_development_dependency 'minitest'
|
16
17
|
s.files = Dir['lib/**/*'] + %w(zoidberg.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zoidberg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mono_logger
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: pry
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,7 +77,21 @@ files:
|
|
63
77
|
- LICENSE
|
64
78
|
- README.md
|
65
79
|
- lib/zoidberg.rb
|
80
|
+
- lib/zoidberg/future.rb
|
81
|
+
- lib/zoidberg/logger.rb
|
82
|
+
- lib/zoidberg/pool.rb
|
83
|
+
- lib/zoidberg/proxy.rb
|
84
|
+
- lib/zoidberg/proxy/confined.rb
|
85
|
+
- lib/zoidberg/proxy/liberated.rb
|
86
|
+
- lib/zoidberg/registry.rb
|
87
|
+
- lib/zoidberg/shell.rb
|
88
|
+
- lib/zoidberg/signal.rb
|
89
|
+
- lib/zoidberg/supervise.rb
|
90
|
+
- lib/zoidberg/supervisor.rb
|
91
|
+
- lib/zoidberg/task.rb
|
92
|
+
- lib/zoidberg/timer.rb
|
66
93
|
- lib/zoidberg/version.rb
|
94
|
+
- lib/zoidberg/weak_ref.rb
|
67
95
|
- zoidberg.gemspec
|
68
96
|
homepage: https://github.com/spox/zoidberg
|
69
97
|
licenses:
|
@@ -90,3 +118,4 @@ signing_key:
|
|
90
118
|
specification_version: 4
|
91
119
|
summary: Why not?
|
92
120
|
test_files: []
|
121
|
+
has_rdoc:
|