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.
Files changed (67) hide show
  1. data/lib/engineyard-serverside.rb +3 -1
  2. data/lib/engineyard-serverside/cli.rb +11 -19
  3. data/lib/engineyard-serverside/deploy.rb +3 -3
  4. data/lib/engineyard-serverside/future.rb +33 -0
  5. data/lib/engineyard-serverside/futures/celluloid.rb +25 -0
  6. data/lib/engineyard-serverside/futures/dataflow.rb +25 -0
  7. data/lib/engineyard-serverside/logged_output.rb +8 -3
  8. data/lib/engineyard-serverside/task.rb +9 -12
  9. data/lib/engineyard-serverside/version.rb +1 -1
  10. data/lib/vendor/celluloid/lib/celluloid.rb +261 -0
  11. data/lib/vendor/celluloid/lib/celluloid/actor.rb +242 -0
  12. data/lib/vendor/celluloid/lib/celluloid/actor_pool.rb +54 -0
  13. data/lib/vendor/celluloid/lib/celluloid/actor_proxy.rb +75 -0
  14. data/lib/vendor/celluloid/lib/celluloid/application.rb +78 -0
  15. data/lib/vendor/celluloid/lib/celluloid/calls.rb +94 -0
  16. data/lib/vendor/celluloid/lib/celluloid/core_ext.rb +14 -0
  17. data/lib/vendor/celluloid/lib/celluloid/events.rb +14 -0
  18. data/lib/vendor/celluloid/lib/celluloid/fiber.rb +33 -0
  19. data/lib/vendor/celluloid/lib/celluloid/fsm.rb +141 -0
  20. data/lib/vendor/celluloid/lib/celluloid/future.rb +60 -0
  21. data/lib/vendor/celluloid/lib/celluloid/links.rb +61 -0
  22. data/lib/vendor/celluloid/lib/celluloid/logger.rb +32 -0
  23. data/lib/vendor/celluloid/lib/celluloid/mailbox.rb +124 -0
  24. data/lib/vendor/celluloid/lib/celluloid/receivers.rb +66 -0
  25. data/lib/vendor/celluloid/lib/celluloid/registry.rb +33 -0
  26. data/lib/vendor/celluloid/lib/celluloid/responses.rb +26 -0
  27. data/lib/vendor/celluloid/lib/celluloid/rspec.rb +2 -0
  28. data/lib/vendor/celluloid/lib/celluloid/signals.rb +50 -0
  29. data/lib/vendor/celluloid/lib/celluloid/supervisor.rb +57 -0
  30. data/lib/vendor/celluloid/lib/celluloid/task.rb +73 -0
  31. data/lib/vendor/celluloid/lib/celluloid/tcp_server.rb +33 -0
  32. data/lib/vendor/celluloid/lib/celluloid/timers.rb +109 -0
  33. data/lib/vendor/celluloid/lib/celluloid/version.rb +4 -0
  34. data/lib/vendor/dataflow/dataflow.rb +124 -0
  35. data/lib/vendor/dataflow/dataflow/actor.rb +22 -0
  36. data/lib/vendor/dataflow/dataflow/equality.rb +44 -0
  37. data/lib/vendor/dataflow/dataflow/future_queue.rb +24 -0
  38. data/lib/vendor/dataflow/dataflow/port.rb +54 -0
  39. data/lib/vendor/open4/lib/open4.rb +432 -0
  40. data/lib/vendor/thor/lib/thor.rb +244 -0
  41. data/lib/vendor/thor/lib/thor/actions.rb +275 -0
  42. data/lib/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  43. data/lib/vendor/thor/lib/thor/actions/directory.rb +91 -0
  44. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
  45. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
  46. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
  47. data/lib/vendor/thor/lib/thor/base.rb +540 -0
  48. data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
  49. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  50. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
  51. data/lib/vendor/thor/lib/thor/error.rb +30 -0
  52. data/lib/vendor/thor/lib/thor/group.rb +271 -0
  53. data/lib/vendor/thor/lib/thor/invocation.rb +180 -0
  54. data/lib/vendor/thor/lib/thor/parser.rb +4 -0
  55. data/lib/vendor/thor/lib/thor/parser/argument.rb +67 -0
  56. data/lib/vendor/thor/lib/thor/parser/arguments.rb +150 -0
  57. data/lib/vendor/thor/lib/thor/parser/option.rb +128 -0
  58. data/lib/vendor/thor/lib/thor/parser/options.rb +169 -0
  59. data/lib/vendor/thor/lib/thor/rake_compat.rb +66 -0
  60. data/lib/vendor/thor/lib/thor/runner.rb +314 -0
  61. data/lib/vendor/thor/lib/thor/shell.rb +83 -0
  62. data/lib/vendor/thor/lib/thor/shell/basic.rb +239 -0
  63. data/lib/vendor/thor/lib/thor/shell/color.rb +108 -0
  64. data/lib/vendor/thor/lib/thor/task.rb +102 -0
  65. data/lib/vendor/thor/lib/thor/util.rb +230 -0
  66. data/lib/vendor/thor/lib/thor/version.rb +3 -0
  67. metadata +70 -10
@@ -0,0 +1,124 @@
1
+ require 'thread'
2
+
3
+ module Celluloid
4
+ class MailboxError < StandardError; end # you can't message the dead
5
+ class MailboxShutdown < StandardError; end # raised if the mailbox can no longer be used
6
+
7
+ # Actors communicate with asynchronous messages. Messages are buffered in
8
+ # Mailboxes until Actors can act upon them.
9
+ class Mailbox
10
+ include Enumerable
11
+
12
+ # A unique address at which this mailbox can be found
13
+ alias_method :address, :object_id
14
+
15
+ def initialize
16
+ @messages = []
17
+ @lock = Mutex.new
18
+ @dead = false
19
+ @condition = ConditionVariable.new
20
+ end
21
+
22
+ # Add a message to the Mailbox
23
+ def <<(message)
24
+ @lock.synchronize do
25
+ raise MailboxError, "dead recipient" if @dead
26
+
27
+ @messages << message
28
+ @condition.signal
29
+ end
30
+ nil
31
+ end
32
+
33
+ # Add a high-priority system event to the Mailbox
34
+ def system_event(event)
35
+ @lock.synchronize do
36
+ unless @dead # Silently fail if messages are sent to dead actors
37
+ @messages.unshift event
38
+ @condition.signal
39
+ end
40
+ end
41
+ nil
42
+ end
43
+
44
+ # Receive a message from the Mailbox
45
+ def receive(timeout = nil, &block)
46
+ message = nil
47
+
48
+ @lock.synchronize do
49
+ raise MailboxError, "attempted to receive from a dead mailbox" if @dead
50
+
51
+ begin
52
+ message = next_message(&block)
53
+
54
+ unless message
55
+ if timeout
56
+ now = Time.now
57
+ wait_until ||= now + timeout
58
+ wait_interval = wait_until - now
59
+ return if wait_interval < 0
60
+ else
61
+ wait_interval = nil
62
+ end
63
+
64
+ @condition.wait(@lock, wait_interval)
65
+ end
66
+ end until message
67
+ end
68
+
69
+ message
70
+ end
71
+
72
+ # Retrieve the next message in the mailbox
73
+ def next_message
74
+ message = nil
75
+
76
+ if block_given?
77
+ index = @messages.index do |msg|
78
+ yield(msg) || msg.is_a?(SystemEvent)
79
+ end
80
+
81
+ message = @messages.slice!(index, 1).first if index
82
+ else
83
+ message = @messages.shift
84
+ end
85
+
86
+ raise message if message.is_a? SystemEvent
87
+ message
88
+ end
89
+
90
+ # Shut down this mailbox and clean up its contents
91
+ def shutdown
92
+ messages = nil
93
+
94
+ @lock.synchronize do
95
+ messages = @messages
96
+ @messages = []
97
+ @dead = true
98
+ end
99
+
100
+ messages.each { |msg| msg.cleanup if msg.respond_to? :cleanup }
101
+ true
102
+ end
103
+
104
+ # Is the mailbox alive?
105
+ def alive?
106
+ !@dead
107
+ end
108
+
109
+ # Cast to an array
110
+ def to_a
111
+ @lock.synchronize { @messages.dup }
112
+ end
113
+
114
+ # Iterate through the mailbox
115
+ def each(&block)
116
+ to_a.each(&block)
117
+ end
118
+
119
+ # Inspect the contents of the Mailbox
120
+ def inspect
121
+ "#<#{self.class}:#{object_id.to_s(16)} @messages=[#{map { |m| m.inspect }.join(', ')}]>"
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,66 @@
1
+ require 'set'
2
+
3
+ module Celluloid
4
+ # Allow methods to directly interact with the actor protocol
5
+ class Receivers
6
+ def initialize
7
+ @receivers = Set.new
8
+ @timers = Timers.new
9
+ end
10
+
11
+ # Receive an asynchronous message
12
+ def receive(timeout = nil, &block)
13
+ receiver = Receiver.new block
14
+
15
+ if timeout
16
+ receiver.timer = @timers.add(timeout) do
17
+ @receivers.delete receiver
18
+ receiver.resume
19
+ end
20
+ end
21
+
22
+ @receivers << receiver
23
+ Task.suspend
24
+ end
25
+
26
+ # How long to wait until the next timer fires
27
+ def wait_interval
28
+ @timers.wait_interval
29
+ end
30
+
31
+ # Fire any pending timers
32
+ def fire_timers
33
+ @timers.fire
34
+ end
35
+
36
+ # Handle incoming messages
37
+ def handle_message(message)
38
+ receiver = @receivers.find { |r| r.match(message) }
39
+ return unless receiver
40
+
41
+ @receivers.delete receiver
42
+ @timers.cancel receiver.timer if receiver.timer
43
+ receiver.resume message
44
+ end
45
+ end
46
+
47
+ # Methods blocking on a call to receive
48
+ class Receiver
49
+ attr_accessor :timer
50
+
51
+ def initialize(block)
52
+ @block = block
53
+ @task = Task.current
54
+ @timer = nil
55
+ end
56
+
57
+ # Match a message with this receiver's block
58
+ def match(message)
59
+ @block.call(message) if @block
60
+ end
61
+
62
+ def resume(message = nil)
63
+ @task.resume message
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ require 'thread'
2
+
3
+ module Celluloid
4
+ # The Registry allows us to refer to specific actors by human-meaningful names
5
+ module Registry
6
+ @@registry = {}
7
+ @@registry_lock = Mutex.new
8
+
9
+ # Register an Actor
10
+ def []=(name, actor)
11
+ actor_singleton = class << actor; self; end
12
+ unless actor_singleton.ancestors.include? ActorProxy
13
+ raise TypeError, "not an actor"
14
+ end
15
+
16
+ @@registry_lock.synchronize do
17
+ @@registry[name.to_sym] = actor
18
+ end
19
+ end
20
+
21
+ # Retrieve an actor by name
22
+ def [](name)
23
+ @@registry_lock.synchronize do
24
+ @@registry[name.to_sym]
25
+ end
26
+ end
27
+
28
+ # List all registered actors by name
29
+ def registered
30
+ @@registry_lock.synchronize { @@registry.keys }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Celluloid
2
+ # Responses to calls
3
+ class Response
4
+ attr_reader :call_id, :value
5
+
6
+ def initialize(call_id, value)
7
+ @call_id, @value = call_id, value
8
+ end
9
+ end
10
+
11
+ # Call completed successfully
12
+ class SuccessResponse < Response; end
13
+
14
+ # Call was aborted due to caller error
15
+ class ErrorResponse < Response
16
+ def value
17
+ if super.is_a? AbortError
18
+ # Aborts are caused by caller error, so ensure they capture the
19
+ # caller's backtrace instead of the receiver's
20
+ raise super.cause.class.new(super.cause.message)
21
+ else
22
+ raise super
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,2 @@
1
+ require File.expand_path('../../../spec/support/actor_examples', __FILE__)
2
+ require File.expand_path('../../../spec/support/mailbox_examples', __FILE__)
@@ -0,0 +1,50 @@
1
+ module Celluloid
2
+ # Event signaling between methods of the same object
3
+ class Signals
4
+ attr_reader :waiting
5
+
6
+ def initialize
7
+ @waiting = {}
8
+ end
9
+
10
+ # Wait for the given signal and return the associated value
11
+ def wait(signal)
12
+ tasks = @waiting[signal]
13
+
14
+ case tasks
15
+ when Array
16
+ tasks << Task.current
17
+ when NilClass
18
+ @waiting[signal] = Task.current
19
+ else
20
+ @waiting[signal] = [tasks, Task.current]
21
+ end
22
+
23
+ Task.suspend
24
+ end
25
+
26
+ # Send a signal to all method calls waiting for the given name
27
+ # Returns true if any calls were signaled, or false otherwise
28
+ def send(name, value = nil)
29
+ tasks = @waiting.delete name
30
+
31
+ case tasks
32
+ when Array
33
+ tasks.each { |task| run_task task, value }
34
+ when NilClass
35
+ Logger.debug("spurious signal: #{name}")
36
+ else
37
+ run_task tasks, value
38
+ end
39
+
40
+ value
41
+ end
42
+
43
+ # Run the given task, reporting errors that occur
44
+ def run_task(task, value)
45
+ task.resume(value)
46
+ rescue => ex
47
+ Celluloid::Logger.crash("signaling error", ex)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,57 @@
1
+ module Celluloid
2
+ # Supervisors are actors that watch over other actors and restart them if
3
+ # they crash
4
+ class Supervisor
5
+ include Celluloid
6
+ trap_exit :restart_actor
7
+
8
+ # Retrieve the actor this supervisor is supervising
9
+ attr_reader :actor
10
+
11
+ def self.supervise(klass, *args, &block)
12
+ new(nil, klass, *args, &block)
13
+ end
14
+
15
+ def self.supervise_as(name, klass, *args, &block)
16
+ new(name, klass, *args, &block)
17
+ end
18
+
19
+ def initialize(name, klass, *args, &block)
20
+ @name, @klass, @args, @block = name, klass, args, block
21
+ @started = false
22
+
23
+ start_actor
24
+ end
25
+
26
+ def start_actor(start_attempts = 3, sleep_interval = 30)
27
+ failures = 0
28
+
29
+ begin
30
+ @actor = @klass.new_link(*@args, &@block)
31
+ rescue => ex
32
+ failures += 1
33
+ if failures >= start_attempts
34
+ failures = 0
35
+
36
+ Logger.warn("#{@klass} is crashing on initialize too quickly, sleeping for #{sleep_interval} seconds")
37
+ sleep sleep_interval
38
+ end
39
+ retry
40
+ end
41
+
42
+ @started = true
43
+ Actor[@name] = @actor if @name
44
+ end
45
+
46
+ # When actors die, regardless of the reason, restart them
47
+ def restart_actor(actor, reason)
48
+ start_actor if @started
49
+ end
50
+
51
+ def inspect
52
+ str = "#<#{self.class}(#{@klass}):0x#{object_id.to_s(16)}"
53
+ str << " " << @args.map { |arg| arg.inspect }.join(' ') unless @args.empty?
54
+ str << ">"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,73 @@
1
+ module Celluloid
2
+ # Trying to resume a dead task
3
+ class DeadTaskError < StandardError; end
4
+
5
+ # Tasks are interruptable/resumable execution contexts used to run methods
6
+ class Task
7
+ class TerminatedError < StandardError; end # kill a running fiber
8
+
9
+ attr_reader :type # what type of task is this?
10
+
11
+ # Obtain the current task
12
+ def self.current
13
+ task = Fiber.current.task
14
+ raise "not in task scope" unless task
15
+ task
16
+ end
17
+
18
+ # Suspend the running task, deferring to the scheduler
19
+ def self.suspend(value = nil)
20
+ result = Fiber.yield(value)
21
+ raise TerminatedError, "task was terminated" if result == TerminatedError
22
+ result
23
+ end
24
+
25
+ # Run the given block within a task
26
+ def initialize(type)
27
+ @type = type
28
+
29
+ actor = Thread.current[:actor]
30
+ mailbox = Thread.current[:mailbox]
31
+
32
+ @fiber = Fiber.new do
33
+ Thread.current[:actor] = actor
34
+ Thread.current[:mailbox] = mailbox
35
+
36
+ Fiber.current.task = self
37
+
38
+ begin
39
+ yield
40
+ rescue TerminatedError
41
+ # Task was explicitly terminated
42
+ end
43
+ end
44
+ end
45
+
46
+ # Resume a suspended task, giving it a value to return if needed
47
+ def resume(value = nil)
48
+ @fiber.resume value
49
+ nil
50
+ rescue FiberError
51
+ raise DeadTaskError, "cannot resume a dead task"
52
+ rescue RuntimeError => ex
53
+ # These occur spuriously on 1.9.3 if we shut down an actor with running tasks
54
+ return if ex.message == ""
55
+ raise
56
+ end
57
+
58
+ # Terminate this task
59
+ def terminate
60
+ resume TerminatedError
61
+ rescue FiberError
62
+ # If we're getting this the task should already be dead
63
+ end
64
+
65
+ # Is the current task still running?
66
+ def running?; @fiber.alive?; end
67
+
68
+ # Nicer string inspect for tasks
69
+ def inspect
70
+ "<Celluloid::Task:0x#{object_id.to_s(16)} @type=#{@type.inspect}, @running=#{@fiber.alive?}>"
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,33 @@
1
+ require 'socket'
2
+
3
+ module Celluloid
4
+ # A TCPServer that runs as an actor
5
+ class TCPServer
6
+ include Celluloid::IO
7
+
8
+ # Bind a TCP server to the given host and port
9
+ def initialize(host, port)
10
+ @server = ::TCPServer.new host, port
11
+ run!
12
+ end
13
+
14
+ # Run the TCP server event loop
15
+ def run
16
+ while true
17
+ wait_readable(@server)
18
+ on_connect @server.accept
19
+ end
20
+ end
21
+
22
+ # Terminate this server
23
+ def terminate
24
+ @server.close
25
+ super
26
+ end
27
+
28
+ # Called whenever a new connection is opened
29
+ def on_connect(connection)
30
+ connection.close
31
+ end
32
+ end
33
+ end