engineyard-serverside 1.5.23.ruby19.8 → 1.5.23.ruby19.9
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/lib/engineyard-serverside.rb +3 -1
- data/lib/engineyard-serverside/cli.rb +11 -19
- data/lib/engineyard-serverside/deploy.rb +3 -3
- data/lib/engineyard-serverside/future.rb +33 -0
- data/lib/engineyard-serverside/futures/celluloid.rb +25 -0
- data/lib/engineyard-serverside/futures/dataflow.rb +25 -0
- data/lib/engineyard-serverside/logged_output.rb +8 -3
- data/lib/engineyard-serverside/task.rb +9 -12
- data/lib/engineyard-serverside/version.rb +1 -1
- data/lib/vendor/celluloid/lib/celluloid.rb +261 -0
- data/lib/vendor/celluloid/lib/celluloid/actor.rb +242 -0
- data/lib/vendor/celluloid/lib/celluloid/actor_pool.rb +54 -0
- data/lib/vendor/celluloid/lib/celluloid/actor_proxy.rb +75 -0
- data/lib/vendor/celluloid/lib/celluloid/application.rb +78 -0
- data/lib/vendor/celluloid/lib/celluloid/calls.rb +94 -0
- data/lib/vendor/celluloid/lib/celluloid/core_ext.rb +14 -0
- data/lib/vendor/celluloid/lib/celluloid/events.rb +14 -0
- data/lib/vendor/celluloid/lib/celluloid/fiber.rb +33 -0
- data/lib/vendor/celluloid/lib/celluloid/fsm.rb +141 -0
- data/lib/vendor/celluloid/lib/celluloid/future.rb +60 -0
- data/lib/vendor/celluloid/lib/celluloid/links.rb +61 -0
- data/lib/vendor/celluloid/lib/celluloid/logger.rb +32 -0
- data/lib/vendor/celluloid/lib/celluloid/mailbox.rb +124 -0
- data/lib/vendor/celluloid/lib/celluloid/receivers.rb +66 -0
- data/lib/vendor/celluloid/lib/celluloid/registry.rb +33 -0
- data/lib/vendor/celluloid/lib/celluloid/responses.rb +26 -0
- data/lib/vendor/celluloid/lib/celluloid/rspec.rb +2 -0
- data/lib/vendor/celluloid/lib/celluloid/signals.rb +50 -0
- data/lib/vendor/celluloid/lib/celluloid/supervisor.rb +57 -0
- data/lib/vendor/celluloid/lib/celluloid/task.rb +73 -0
- data/lib/vendor/celluloid/lib/celluloid/tcp_server.rb +33 -0
- data/lib/vendor/celluloid/lib/celluloid/timers.rb +109 -0
- data/lib/vendor/celluloid/lib/celluloid/version.rb +4 -0
- data/lib/vendor/dataflow/dataflow.rb +124 -0
- data/lib/vendor/dataflow/dataflow/actor.rb +22 -0
- data/lib/vendor/dataflow/dataflow/equality.rb +44 -0
- data/lib/vendor/dataflow/dataflow/future_queue.rb +24 -0
- data/lib/vendor/dataflow/dataflow/port.rb +54 -0
- data/lib/vendor/open4/lib/open4.rb +432 -0
- data/lib/vendor/thor/lib/thor.rb +244 -0
- data/lib/vendor/thor/lib/thor/actions.rb +275 -0
- data/lib/vendor/thor/lib/thor/actions/create_file.rb +103 -0
- data/lib/vendor/thor/lib/thor/actions/directory.rb +91 -0
- data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
- data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
- data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
- data/lib/vendor/thor/lib/thor/base.rb +540 -0
- data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/vendor/thor/lib/thor/error.rb +30 -0
- data/lib/vendor/thor/lib/thor/group.rb +271 -0
- data/lib/vendor/thor/lib/thor/invocation.rb +180 -0
- data/lib/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/vendor/thor/lib/thor/parser/argument.rb +67 -0
- data/lib/vendor/thor/lib/thor/parser/arguments.rb +150 -0
- data/lib/vendor/thor/lib/thor/parser/option.rb +128 -0
- data/lib/vendor/thor/lib/thor/parser/options.rb +169 -0
- data/lib/vendor/thor/lib/thor/rake_compat.rb +66 -0
- data/lib/vendor/thor/lib/thor/runner.rb +314 -0
- data/lib/vendor/thor/lib/thor/shell.rb +83 -0
- data/lib/vendor/thor/lib/thor/shell/basic.rb +239 -0
- data/lib/vendor/thor/lib/thor/shell/color.rb +108 -0
- data/lib/vendor/thor/lib/thor/task.rb +102 -0
- data/lib/vendor/thor/lib/thor/util.rb +230 -0
- data/lib/vendor/thor/lib/thor/version.rb +3 -0
- metadata +70 -10
@@ -0,0 +1,94 @@
|
|
1
|
+
module Celluloid
|
2
|
+
# Calls represent requests to an actor
|
3
|
+
class Call
|
4
|
+
attr_reader :id, :caller, :method, :arguments, :block
|
5
|
+
|
6
|
+
def initialize(caller, method, arguments, block)
|
7
|
+
@id = object_id # memoize object ID for serialization
|
8
|
+
@caller, @method, @arguments, @block = caller, method, arguments, block
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_signature(obj)
|
12
|
+
unless obj.respond_to? @method
|
13
|
+
raise NoMethodError, "undefined method `#{@method}' for #{obj.inspect}"
|
14
|
+
end
|
15
|
+
|
16
|
+
arity = obj.method(@method).arity
|
17
|
+
if arity >= 0
|
18
|
+
if arguments.size != arity
|
19
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.size} for #{arity})"
|
20
|
+
end
|
21
|
+
elsif arity < -1
|
22
|
+
mandatory_args = -arity - 1
|
23
|
+
if arguments.size < mandatory_args
|
24
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.size} for #{mandatory_args})"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Synchronous calls wait for a response
|
31
|
+
class SyncCall < Call
|
32
|
+
def dispatch(obj)
|
33
|
+
begin
|
34
|
+
check_signature(obj)
|
35
|
+
rescue Exception => ex
|
36
|
+
respond ErrorResponse.new(@id, AbortError.new(ex))
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
begin
|
41
|
+
result = obj.send @method, *@arguments, &@block
|
42
|
+
rescue Exception => exception
|
43
|
+
# Exceptions that occur during synchronous calls are reraised in the
|
44
|
+
# context of the caller
|
45
|
+
respond ErrorResponse.new(@id, exception)
|
46
|
+
|
47
|
+
if exception.is_a? AbortError
|
48
|
+
# Aborting indicates a protocol error on the part of the caller
|
49
|
+
# It should crash the caller, but the exception isn't reraised
|
50
|
+
return
|
51
|
+
else
|
52
|
+
# Otherwise, it's a bug in this actor and should be reraised
|
53
|
+
raise exception
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
respond SuccessResponse.new(@id, result)
|
58
|
+
end
|
59
|
+
|
60
|
+
def cleanup
|
61
|
+
exception = DeadActorError.new("attempted to call a dead actor")
|
62
|
+
respond ErrorResponse.new(@id, exception)
|
63
|
+
end
|
64
|
+
|
65
|
+
#######
|
66
|
+
private
|
67
|
+
#######
|
68
|
+
|
69
|
+
def respond(message)
|
70
|
+
@caller << message
|
71
|
+
rescue MailboxError
|
72
|
+
# It's possible the caller exited or crashed before we could send a
|
73
|
+
# response to them.
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Asynchronous calls don't wait for a response
|
78
|
+
class AsyncCall < Call
|
79
|
+
def dispatch(obj)
|
80
|
+
begin
|
81
|
+
check_signature(obj)
|
82
|
+
rescue Exception => ex
|
83
|
+
Logger.crash("#{obj.class}: async call failed!", ex)
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
obj.send(@method, *@arguments, &@block)
|
88
|
+
rescue AbortError => ex
|
89
|
+
# Swallow aborted async calls, as they indicate the caller made a mistake
|
90
|
+
Logger.crash("#{obj.class}: async call aborted!", ex)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'celluloid/fiber'
|
2
|
+
|
3
|
+
# Monkeypatch Thread to allow lazy access to its Celluloid::Mailbox
|
4
|
+
class Thread
|
5
|
+
# Retrieve the mailbox for the current thread or lazily initialize it
|
6
|
+
def self.mailbox
|
7
|
+
current[:mailbox] ||= Celluloid::Mailbox.new
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Fiber
|
12
|
+
# Celluloid::Task associated with this Fiber
|
13
|
+
attr_accessor :task
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Celluloid
|
2
|
+
# Exceptional system events which need to be processed out of band
|
3
|
+
class SystemEvent < Exception; end
|
4
|
+
|
5
|
+
# An actor has exited for the given reason
|
6
|
+
class ExitEvent < SystemEvent
|
7
|
+
attr_reader :actor, :reason
|
8
|
+
|
9
|
+
def initialize(actor, reason = nil)
|
10
|
+
@actor, @reason = actor, reason
|
11
|
+
super reason.to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Fibers are hard... let's go shopping!
|
2
|
+
begin
|
3
|
+
require 'fiber'
|
4
|
+
rescue LoadError => ex
|
5
|
+
if defined? JRUBY_VERSION
|
6
|
+
if RUBY_VERSION < "1.9.2"
|
7
|
+
raise LoadError, "Celluloid requires JRuby 1.9 mode. Please pass the --1.9 flag or set JRUBY_OPTS=--1.9"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Fibers are broken on JRuby 1.6.5. This works around the issue
|
11
|
+
if JRUBY_VERSION == "1.6.5"
|
12
|
+
require 'jruby'
|
13
|
+
org.jruby.ext.fiber.FiberExtLibrary.new.load(JRuby.runtime, false)
|
14
|
+
class org::jruby::ext::fiber::ThreadFiber
|
15
|
+
field_accessor :state
|
16
|
+
end
|
17
|
+
|
18
|
+
class Fiber
|
19
|
+
def alive?
|
20
|
+
JRuby.reference(self).state != org.jruby.ext.fiber.ThreadFiberState::FINISHED
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
# Just in case subsequent JRuby releases have broken fibers :/
|
25
|
+
raise ex
|
26
|
+
end
|
27
|
+
elsif defined? Rubinius
|
28
|
+
# If we're on Rubinius, we can still work in 1.8 mode
|
29
|
+
Fiber = Rubinius::Fiber
|
30
|
+
else
|
31
|
+
raise ex
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Celluloid
|
2
|
+
# Turn concurrent objects into finite state machines
|
3
|
+
# Inspired by Erlang's gen_fsm. See http://www.erlang.org/doc/man/gen_fsm.html
|
4
|
+
module FSM
|
5
|
+
DEFAULT_STATE = :default # Default state name unless one is explicitly set
|
6
|
+
|
7
|
+
# Included hook to extend class methods
|
8
|
+
def self.included(klass)
|
9
|
+
klass.send :include, Celluloid
|
10
|
+
klass.send :extend, ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
# Ensure FSMs transition into the default state after they're initialized
|
15
|
+
def new(*args, &block)
|
16
|
+
fsm = super
|
17
|
+
fsm.transition default_state
|
18
|
+
fsm
|
19
|
+
end
|
20
|
+
|
21
|
+
# Ensure FSMs transition into the default state after they're initialized
|
22
|
+
def new_link(*args, &block)
|
23
|
+
fsm = super
|
24
|
+
fsm.transition default_state
|
25
|
+
fsm
|
26
|
+
end
|
27
|
+
|
28
|
+
# Obtain or set the default state
|
29
|
+
# Passing a state name sets the default state
|
30
|
+
def default_state(new_default = nil)
|
31
|
+
if new_default
|
32
|
+
@default_state = new_default.to_sym
|
33
|
+
else
|
34
|
+
defined?(@default_state) ? @default_state : DEFAULT_STATE
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Obtain the valid states for this FSM
|
39
|
+
def states
|
40
|
+
@states ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Declare an FSM state and optionally provide a callback block to fire
|
44
|
+
# Options:
|
45
|
+
# * to: a state or array of states this state can transition to
|
46
|
+
def state(*args, &block)
|
47
|
+
if args.last.is_a? Hash
|
48
|
+
options = args.pop.inject({}) { |h,(k,v)| h[k.to_s] = v; h }
|
49
|
+
else
|
50
|
+
options = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
args.each do |name|
|
54
|
+
name = name.to_sym
|
55
|
+
states[name] = State.new(name, options['to'], &block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Obtain the current state of the FSM
|
61
|
+
def current_state
|
62
|
+
defined?(@state) ? @state : @state = self.class.default_state
|
63
|
+
end
|
64
|
+
alias_method :state, :current_state
|
65
|
+
|
66
|
+
# Transition to another state
|
67
|
+
# Options:
|
68
|
+
# * delay: don't transition immediately, wait the given number of seconds.
|
69
|
+
# This will return a Celluloid::Timer object you can use to
|
70
|
+
# cancel the pending state transition.
|
71
|
+
#
|
72
|
+
# Note: making additional state transitions will cancel delayed transitions
|
73
|
+
def transition(state_name, options = {})
|
74
|
+
state_name = state_name.to_sym
|
75
|
+
current_state = self.class.states[@state]
|
76
|
+
|
77
|
+
return if current_state && current_state.name == state_name
|
78
|
+
|
79
|
+
if current_state and not current_state.valid_transition? state_name
|
80
|
+
valid = current_state.transitions.map(&:to_s).join(", ")
|
81
|
+
raise ArgumentError, "#{self.class} can't change state from '#{@state}' to '#{state_name}', only to: #{valid}"
|
82
|
+
end
|
83
|
+
|
84
|
+
new_state = self.class.states[state_name]
|
85
|
+
|
86
|
+
if !new_state and state_name == self.class.default_state
|
87
|
+
# FIXME This probably isn't thread safe... or wise
|
88
|
+
new_state = self.class.states[state_name] = State.new(state_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
if new_state
|
92
|
+
if options[:delay]
|
93
|
+
@delayed_transition.cancel if @delayed_transition
|
94
|
+
|
95
|
+
@delayed_transition = after(options[:delay]) do
|
96
|
+
transition! new_state.name
|
97
|
+
new_state.call(self)
|
98
|
+
end
|
99
|
+
|
100
|
+
return @delayed_transition
|
101
|
+
end
|
102
|
+
|
103
|
+
if defined?(@delayed_transition) and @delayed_transition
|
104
|
+
@delayed_transition.cancel
|
105
|
+
@delayed_transition = nil
|
106
|
+
end
|
107
|
+
|
108
|
+
transition! new_state.name
|
109
|
+
new_state.call(self)
|
110
|
+
else
|
111
|
+
raise ArgumentError, "invalid state for #{self.class}: #{state_name}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Immediate state transition with no sanity checks. "Dangerous!"
|
116
|
+
def transition!(state_name)
|
117
|
+
@state = state_name
|
118
|
+
end
|
119
|
+
|
120
|
+
# FSM states as declared by Celluloid::FSM.state
|
121
|
+
class State
|
122
|
+
attr_reader :name, :transitions
|
123
|
+
|
124
|
+
def initialize(name, transitions = nil, &block)
|
125
|
+
@name, @block = name, block
|
126
|
+
@transitions = Array(transitions).map { |t| t.to_sym } if transitions
|
127
|
+
end
|
128
|
+
|
129
|
+
def call(obj)
|
130
|
+
obj.instance_eval(&@block) if @block
|
131
|
+
end
|
132
|
+
|
133
|
+
def valid_transition?(new_state)
|
134
|
+
# All transitions are allowed unless expressly
|
135
|
+
return true unless @transitions
|
136
|
+
|
137
|
+
@transitions.include? new_state.to_sym
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
# Celluloid::Future objects allow methods and blocks to run in the
|
5
|
+
# background, their values requested later
|
6
|
+
class Future
|
7
|
+
# Create a new Celluloid::Future object, allowing a block to be computed in
|
8
|
+
# the background and its return value obtained later
|
9
|
+
def initialize(*args, &block)
|
10
|
+
@lock = Mutex.new
|
11
|
+
@value_obtained = false
|
12
|
+
|
13
|
+
@runner = Runner.new(*args, &block)
|
14
|
+
@runner.run!
|
15
|
+
end
|
16
|
+
|
17
|
+
# Obtain the value for this Future
|
18
|
+
def value
|
19
|
+
@lock.synchronize do
|
20
|
+
unless @value_obtained
|
21
|
+
@value = @runner.value
|
22
|
+
@runner.terminate
|
23
|
+
@value_obtained = true
|
24
|
+
end
|
25
|
+
|
26
|
+
@value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias_method :call, :value
|
30
|
+
|
31
|
+
# Inspect this Celluloid::Future
|
32
|
+
alias_method :inspect, :to_s
|
33
|
+
|
34
|
+
# Runner is an internal class which executes the given block/method
|
35
|
+
class Runner
|
36
|
+
include Celluloid
|
37
|
+
|
38
|
+
def initialize(*args, &block)
|
39
|
+
@args, @block = args, block
|
40
|
+
@called = nil
|
41
|
+
@error = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def run
|
45
|
+
@value = @block.call(*@args)
|
46
|
+
rescue Exception => error
|
47
|
+
@error = error
|
48
|
+
ensure
|
49
|
+
@called = true
|
50
|
+
signal :finished
|
51
|
+
end
|
52
|
+
|
53
|
+
def value
|
54
|
+
wait :finished unless @called
|
55
|
+
abort @error if @error
|
56
|
+
@value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
# Thread safe storage of inter-actor links
|
5
|
+
class Links
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@links = {}
|
10
|
+
@lock = Mutex.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add an actor to the current links
|
14
|
+
def <<(actor)
|
15
|
+
@lock.synchronize do
|
16
|
+
@links[actor.mailbox.address] = actor
|
17
|
+
end
|
18
|
+
actor
|
19
|
+
end
|
20
|
+
|
21
|
+
# Do links include the given actor?
|
22
|
+
def include?(actor)
|
23
|
+
@lock.synchronize do
|
24
|
+
@links.has_key? actor.mailbox.address
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Remove an actor from the links
|
29
|
+
def delete(actor)
|
30
|
+
@lock.synchronize do
|
31
|
+
@links.delete actor.mailbox.address
|
32
|
+
end
|
33
|
+
actor
|
34
|
+
end
|
35
|
+
|
36
|
+
# Iterate through all links
|
37
|
+
def each
|
38
|
+
@lock.synchronize do
|
39
|
+
@links.each { |_, actor| yield(actor) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Map across links
|
44
|
+
def map
|
45
|
+
result = []
|
46
|
+
each { |actor| result << yield(actor) }
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
# Send an event message to all actors
|
51
|
+
def send_event(event)
|
52
|
+
each { |actor| actor.mailbox.system_event event }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate a string representation
|
56
|
+
def inspect
|
57
|
+
links = self.map(&:inspect).join(',')
|
58
|
+
"#<#{self.class}[#{links}]>"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Celluloid
|
2
|
+
module Logger
|
3
|
+
module_function
|
4
|
+
|
5
|
+
# Send a debug message
|
6
|
+
def debug(string)
|
7
|
+
Celluloid.logger.debug(string) if Celluloid.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
# Send a info message
|
11
|
+
def info(string)
|
12
|
+
Celluloid.logger.info(string) if Celluloid.logger
|
13
|
+
end
|
14
|
+
|
15
|
+
# Send a warning message
|
16
|
+
def warn(string)
|
17
|
+
Celluloid.logger.warn(string) if Celluloid.logger
|
18
|
+
end
|
19
|
+
|
20
|
+
# Send an error message
|
21
|
+
def error(string)
|
22
|
+
Celluloid.logger.error(string) if Celluloid.logger
|
23
|
+
end
|
24
|
+
|
25
|
+
# Handle a crash
|
26
|
+
def crash(string, exception)
|
27
|
+
string += "\n#{exception.class}: #{exception.to_s}\n"
|
28
|
+
string << exception.backtrace.join("\n")
|
29
|
+
error(string)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|