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
@@ -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'