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
@@ -2,12 +2,13 @@
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path('vendor/escape/lib', File.dirname(__FILE__))
4
4
  $LOAD_PATH.unshift File.expand_path('vendor/json_pure/lib', File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift File.expand_path('vendor/open4/lib', File.dirname(__FILE__))
5
6
 
6
7
  require 'escape'
7
8
  require 'json'
8
9
  require 'tmpdir'
9
- require 'celluloid'
10
10
  require 'thor'
11
+ require 'open4'
11
12
 
12
13
  require 'engineyard-serverside/version'
13
14
  require 'engineyard-serverside/strategies/git'
@@ -19,6 +20,7 @@ require 'engineyard-serverside/lockfile_parser'
19
20
  require 'engineyard-serverside/cli'
20
21
  require 'engineyard-serverside/configuration'
21
22
  require 'engineyard-serverside/deprecation'
23
+ require 'engineyard-serverside/future'
22
24
 
23
25
  module EY
24
26
  module Serverside
@@ -199,24 +199,21 @@ module EY
199
199
  desc "propagate", "Propagate the engineyard-serverside gem to the other instances in the cluster. This will install exactly version #{EY::Serverside::VERSION}."
200
200
  def propagate
201
201
  ey_server_side = Dependency.new('engineyard-serverside', EY::Serverside::VERSION)
202
- futures = EY::Serverside::Server.all.find_all do |server|
203
- !server.local? # of course this machine has it
204
- end.map do |server|
205
- Celluloid::Future.new do
206
- log = {}
202
+ servers = EY::Serverside::Server.all.find_all { |server| !server.local? }
203
+
204
+ futures = EY::Serverside::Future.call(servers) do |server|
205
+ installed = server.gem?(ey_server_side.name, ey_server_side.version)
206
+ unless installed
207
207
  unless server.gem?(ey_server_side.name, ey_server_side.version)
208
- (dependencies + [ey_server_side]).each do |dependency|
209
- unless server.gem?(dependency.name, dependency.version)
210
- puts "~> Installing #{dependency.name} on #{server.hostname}"
211
- server.copy(dependency.local_path, dependency.remote_path)
212
- log[dependency.name] = server.install_gem(dependency.remote_path)
213
- end
214
- end
208
+ puts "~> Installing #{ey_server_side.name} on #{server.hostname}"
209
+ server.copy(ey_server_side.local_path, ey_server_side.remote_path)
210
+ installed = server.install_gem(ey_server_side.remote_path)
215
211
  end
216
- log
217
212
  end
213
+ installed
218
214
  end
219
- futures.map {|f| f.value} unless futures.empty?
215
+
216
+ EY::Serverside::Future.success?(futures)
220
217
  end
221
218
 
222
219
  private
@@ -231,11 +228,6 @@ module EY
231
228
  }
232
229
  end
233
230
 
234
- def dependencies
235
- [Dependency.new('celluloid', Celluloid::VERSION),
236
- Dependency.new('thor', '0.13.3')]
237
- end
238
-
239
231
  class Dependency
240
232
  attr_reader :name, :version
241
233
  def initialize(name, version)
@@ -145,10 +145,10 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
145
145
  # task
146
146
  def push_code
147
147
  info "~> Pushing code to all servers"
148
- futures = EY::Serverside::Server.all.map do |server|
149
- Celluloid::Future.new { server.sync_directory(config.repository_cache) }
148
+ futures = EY::Serverside::Future.call(EY::Serverside::Server.all) do |server|
149
+ server.sync_directory(config.repository_cache)
150
150
  end
151
- futures.all? {|f| f.value == true}
151
+ EY::Serverside::Future.success?(futures)
152
152
  end
153
153
 
154
154
  # task
@@ -0,0 +1,33 @@
1
+ module EY
2
+ module Serverside
3
+ class Future
4
+ def self.success?(futures)
5
+ futures.empty? || futures.all? {|f| f.success?}
6
+ end
7
+
8
+ def initialize(server, *args, &block)
9
+ @server = server
10
+ @args = args
11
+ @block = block
12
+ end
13
+
14
+ def success?
15
+ @value == true
16
+ end
17
+
18
+ def error?
19
+ !success?
20
+ end
21
+
22
+ def inspect
23
+ %Q{<Serverside::Future @server="#{@server.hostname}" @args="#{@args}" @value="#{@value}"}
24
+ end
25
+ end
26
+
27
+ if RUBY_VERSION =~ /1\.8/
28
+ require 'engineyard-serverside/futures/dataflow'
29
+ else
30
+ require 'engineyard-serverside/futures/celluloid'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module EY
2
+ module Serverside
3
+ $LOAD_PATH.unshift File.expand_path('../../vendor/celluloid/lib', File.dirname(__FILE__))
4
+ require 'celluloid'
5
+ class Future
6
+ def self.call(servers, *args, &block)
7
+ futures = servers.map do |server|
8
+ new(server, *args, &block)
9
+ end
10
+
11
+ futures.each {|f| f.call}
12
+ futures
13
+ end
14
+
15
+ def future
16
+ Celluloid::Future.new(@server, *@args, &@block)
17
+ end
18
+
19
+ def call
20
+ # Celluloid needs to call the block explicitely
21
+ @value ||= future.call
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module EY
2
+ module Serverside
3
+ $LOAD_PATH.unshift File.expand_path('../../vendor/dataflow/lib', File.dirname(__FILE__))
4
+ require 'dataflow'
5
+
6
+ class Future
7
+ def self.call(servers, *args, &block)
8
+ futures = barrier(*servers.map do |server|
9
+ new(server, *args, &block)
10
+ end)
11
+
12
+ futures.each {|f| f.call}
13
+ futures
14
+ end
15
+
16
+ def future
17
+ need_later { @block.call(@server, *@args) }
18
+ end
19
+
20
+ def call
21
+ @value ||= future
22
+ end
23
+ end
24
+ end
25
+ end
@@ -57,9 +57,14 @@ module EY
57
57
 
58
58
  def logged_system(cmd)
59
59
  with_logfile do |log|
60
- pid = Process.spawn(cmd, :out => log, :err => log)
61
- Process.waitpid(pid)
62
- $?.success?
60
+ out = verbose? ? Tee.new($stdout, log) : log
61
+ err = Tee.new($stderr, log) # we always want to see errors
62
+
63
+ out << ":: running #{cmd}\n"
64
+
65
+ # :quiet means don't raise an error on nonzero exit status
66
+ status = Open4.spawn cmd, 0 => '', 1 => out, 2 => err, :quiet => true
67
+ status.exitstatus == 0
63
68
  end
64
69
  end
65
70
 
@@ -47,21 +47,18 @@ module EY
47
47
 
48
48
  private
49
49
 
50
- def run_on_roles(cmd, wrapper=%w[sh -l -c])
51
- futures = EY::Serverside::Server.from_roles(@roles).map do |server|
52
- to_run = block_given? ? yield(server, cmd.dup) : cmd
53
- Celluloid::Future.new { server.run(Escape.shell_command(wrapper + [to_run])) }
50
+ def run_on_roles(cmd, wrapper=%w[sh -l -c], &block)
51
+ servers = EY::Serverside::Server.from_roles(@roles)
52
+ futures = EY::Serverside::Future.call(servers, block_given?) do |server, exec_block|
53
+ to_run = exec_block ? block.call(server, cmd.dup) : cmd
54
+ server.run(Escape.shell_command(wrapper + [to_run]))
54
55
  end
55
- # MRI's truthiness check is an internal C thing that does not call
56
- # any methods... so Dataflow cannot proxy it & we must "x == true"
57
- # Rubinius, wherefore art thou!?
58
- unless futures.empty?
59
- results = futures.map {|x| x.value}
60
- results.all?{|x| x == true } || raise(EY::Serverside::RemoteFailure.new("""#{cmd}
61
- Results: #{results}"""))
56
+
57
+ unless EY::Serverside::Future.success?(futures)
58
+ failures = futures.select {|f| f.error? }.map {|f| f.inspect}.join("\n")
59
+ raise EY::Serverside::RemoteFailure.new(failures)
62
60
  end
63
61
  end
64
-
65
62
  end
66
63
  end
67
64
  end
@@ -1,5 +1,5 @@
1
1
  module EY
2
2
  module Serverside
3
- VERSION = '1.5.23.ruby19.8'
3
+ VERSION = '1.5.23.ruby19.9'
4
4
  end
5
5
  end
@@ -0,0 +1,261 @@
1
+ require 'logger'
2
+ require 'thread'
3
+
4
+ module Celluloid
5
+ @logger = Logger.new STDERR
6
+
7
+ class << self
8
+ attr_accessor :logger # Thread-safe logger class
9
+
10
+ def included(klass)
11
+ klass.send :extend, ClassMethods
12
+ end
13
+
14
+ # Are we currently inside of an actor?
15
+ def actor?
16
+ !!Thread.current[:actor]
17
+ end
18
+
19
+ # Obtain the currently running actor (if one exists)
20
+ def current_actor
21
+ actor = Thread.current[:actor]
22
+ raise NotActorError, "not in actor scope" unless actor
23
+ actor.proxy
24
+ end
25
+ alias_method :current, :current_actor
26
+
27
+ # Receive an asynchronous message
28
+ def receive(timeout = nil, &block)
29
+ actor = Thread.current[:actor]
30
+ if actor
31
+ actor.receive(timeout, &block)
32
+ else
33
+ Thread.mailbox.receive(timeout, &block)
34
+ end
35
+ end
36
+
37
+ # Sleep letting the actor continue processing messages
38
+ def sleep(interval)
39
+ actor = Thread.current[:actor]
40
+ if actor
41
+ actor.sleep(interval)
42
+ else
43
+ Kernel.sleep interval
44
+ end
45
+ end
46
+
47
+ # Obtain a hash of active tasks to their current activities
48
+ def tasks
49
+ actor = Thread.current[:actor]
50
+ raise NotActorError, "not in actor scope" unless actor
51
+ actor.tasks
52
+ end
53
+ end
54
+
55
+ # Class methods added to classes which include Celluloid
56
+ module ClassMethods
57
+ # Create a new actor
58
+ def new(*args, &block)
59
+ proxy = Actor.new(allocate).proxy
60
+ proxy.send(:initialize, *args, &block)
61
+ proxy
62
+ end
63
+ alias_method :spawn, :new
64
+
65
+ # Create a new actor and link to the current one
66
+ def new_link(*args, &block)
67
+ current_actor = Celluloid.current_actor
68
+ raise NotActorError, "can't link outside actor context" unless current_actor
69
+
70
+ proxy = Actor.new(allocate).proxy
71
+ current_actor.link proxy
72
+ proxy.send(:initialize, *args, &block)
73
+ proxy
74
+ end
75
+ alias_method :spawn_link, :new_link
76
+
77
+ # Create a supervisor which ensures an instance of an actor will restart
78
+ # an actor if it fails
79
+ def supervise(*args, &block)
80
+ Supervisor.supervise(self, *args, &block)
81
+ end
82
+
83
+ # Create a supervisor which ensures an instance of an actor will restart
84
+ # an actor if it fails, and keep the actor registered under a given name
85
+ def supervise_as(name, *args, &block)
86
+ Supervisor.supervise_as(name, self, *args, &block)
87
+ end
88
+
89
+ # Trap errors from actors we're linked to when they exit
90
+ def trap_exit(callback)
91
+ @exit_handler = callback.to_sym
92
+ end
93
+
94
+ # Obtain the exit handler for this actor
95
+ attr_reader :exit_handler
96
+
97
+ # Configure a custom mailbox factory
98
+ def use_mailbox(klass = nil, &block)
99
+ if block
100
+ define_method(:mailbox_factory, &block)
101
+ else
102
+ define_method(:mailbox_factory) { klass.new }
103
+ end
104
+ end
105
+ end
106
+
107
+ #
108
+ # Instance methods
109
+ #
110
+
111
+ # Is this actor alive?
112
+ def alive?
113
+ Thread.current[:actor].alive?
114
+ end
115
+
116
+ # Raise an exception in caller context, but stay running
117
+ def abort(cause)
118
+ raise AbortError.new(cause)
119
+ end
120
+
121
+ # Terminate this actor
122
+ def terminate
123
+ Thread.current[:actor].terminate
124
+ end
125
+
126
+ def inspect
127
+ str = "#<Celluloid::Actor(#{self.class}:0x#{object_id.to_s(16)})"
128
+ ivars = instance_variables.map do |ivar|
129
+ "#{ivar}=#{instance_variable_get(ivar).inspect}"
130
+ end
131
+
132
+ str << " " << ivars.join(' ') unless ivars.empty?
133
+ str << ">"
134
+ end
135
+
136
+ # Send a signal with the given name to all waiting methods
137
+ def signal(name, value = nil)
138
+ Thread.current[:actor].signal name, value
139
+ end
140
+
141
+ # Wait for the given signal
142
+ def wait(name)
143
+ Thread.current[:actor].wait name
144
+ end
145
+
146
+ # Obtain the current_actor
147
+ def current_actor
148
+ Celluloid.current_actor
149
+ end
150
+
151
+ # Obtain the running tasks for this actor
152
+ def tasks
153
+ Celluloid.tasks
154
+ end
155
+
156
+ # Obtain the Ruby object the actor is wrapping. This should ONLY be used
157
+ # for a limited set of use cases like runtime metaprogramming. Interacting
158
+ # directly with the wrapped object foregoes any kind of thread safety that
159
+ # Celluloid would ordinarily provide you, and the object is guaranteed to
160
+ # be shared with at least the actor thread. Tread carefully.
161
+ def wrapped_object; self; end
162
+
163
+ # Obtain the Celluloid::Links for this actor
164
+ def links
165
+ Thread.current[:actor].links
166
+ end
167
+
168
+ # Link this actor to another, allowing it to crash or react to errors
169
+ def link(actor)
170
+ actor.notify_link current_actor
171
+ notify_link actor
172
+ end
173
+
174
+ # Remove links to another actor
175
+ def unlink(actor)
176
+ actor.notify_unlink current_actor
177
+ notify_unlink actor
178
+ end
179
+
180
+ def notify_link(actor)
181
+ links << actor
182
+ end
183
+
184
+ def notify_unlink(actor)
185
+ links.delete actor
186
+ end
187
+
188
+ # Is this actor linked to another?
189
+ def linked_to?(actor)
190
+ Thread.current[:actor].links.include? actor
191
+ end
192
+
193
+ # Receive an asynchronous message via the actor protocol
194
+ def receive(timeout = nil, &block)
195
+ Celluloid.receive(timeout, &block)
196
+ end
197
+
198
+ # Sleep while letting the actor continue to receive messages
199
+ def sleep(interval)
200
+ Celluloid.sleep(interval)
201
+ end
202
+
203
+ # Call a block after a given interval
204
+ def after(interval, &block)
205
+ Thread.current[:actor].after(interval, &block)
206
+ end
207
+
208
+ # Perform a blocking or computationally intensive action inside an
209
+ # asynchronous thread pool, allowing the caller to continue processing other
210
+ # messages in its mailbox in the meantime
211
+ def async(&block)
212
+ # This implementation relies on the present implementation of
213
+ # Celluloid::Future, which uses an Actor to run the block
214
+ Future.new(&block).value
215
+ end
216
+
217
+ # Process async calls via method_missing
218
+ def method_missing(meth, *args, &block)
219
+ # bang methods are async calls
220
+ if meth.to_s.match(/!$/)
221
+ unbanged_meth = meth.to_s.sub(/!$/, '')
222
+ call = AsyncCall.new(@mailbox, unbanged_meth, args, block)
223
+
224
+ begin
225
+ Thread.current[:actor].mailbox << call
226
+ rescue MailboxError
227
+ # Silently swallow asynchronous calls to dead actors. There's no way
228
+ # to reliably generate DeadActorErrors for async calls, so users of
229
+ # async calls should find other ways to deal with actors dying
230
+ # during an async call (i.e. linking/supervisors)
231
+ end
232
+
233
+ return # casts are async and return immediately
234
+ end
235
+
236
+ super
237
+ end
238
+ end
239
+
240
+ require 'celluloid/version'
241
+ require 'celluloid/actor_proxy'
242
+ require 'celluloid/calls'
243
+ require 'celluloid/core_ext'
244
+ require 'celluloid/events'
245
+ require 'celluloid/fiber'
246
+ require 'celluloid/fsm'
247
+ require 'celluloid/links'
248
+ require 'celluloid/logger'
249
+ require 'celluloid/mailbox'
250
+ require 'celluloid/receivers'
251
+ require 'celluloid/registry'
252
+ require 'celluloid/responses'
253
+ require 'celluloid/signals'
254
+ require 'celluloid/task'
255
+ require 'celluloid/timers'
256
+
257
+ require 'celluloid/actor'
258
+ require 'celluloid/actor_pool'
259
+ require 'celluloid/supervisor'
260
+ require 'celluloid/future'
261
+ require 'celluloid/application'