engineyard-serverside 1.5.23.ruby19.8 → 1.5.23.ruby19.9

Sign up to get free protection for your applications and to get access to all the features.
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