ra-bluepill 0.0.44 → 0.0.45

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.44
1
+ 0.0.45
data/bin/bluepill CHANGED
@@ -6,7 +6,8 @@ require 'bluepill'
6
6
  options = {
7
7
  :log_file => "/var/log/bluepill.log",
8
8
  :base_dir => "/var/bluepill",
9
- :privileged => true
9
+ :privileged => true,
10
+ :timeout => 10
10
11
  }
11
12
 
12
13
  OptionParser.new do |opts|
@@ -28,6 +29,10 @@ OptionParser.new do |opts|
28
29
  options[:privileged] = v
29
30
  end
30
31
 
32
+ opts.on('-t', '--timeout Seconds', Integer, "Timeout for commands sent to the daemon, in seconds. Defaults to 10.") do |timeout|
33
+ options[:timeout] = timeout
34
+ end
35
+
31
36
  help = proc do
32
37
  puts opts
33
38
  puts
@@ -57,7 +62,7 @@ end
57
62
 
58
63
  APPLICATION_COMMANDS = %w(status start stop restart unmonitor quit log)
59
64
 
60
- controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file))
65
+ controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file, :timeout))
61
66
 
62
67
  if controller.running_applications.include?(File.basename($0)) && File.symlink?($0)
63
68
  # bluepill was called as a symlink with the name of the target application
@@ -97,7 +102,7 @@ if options[:command] == "load"
97
102
  file_path = File.expand_path(file)
98
103
 
99
104
  exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
100
-
105
+
101
106
  else
102
107
  $stderr.puts "Can't find file: #{file}"
103
108
  end
@@ -148,7 +148,7 @@ module Bluepill
148
148
  end
149
149
 
150
150
  def setup_signal_traps
151
- terminator = lambda do
151
+ terminator = Proc.new do
152
152
  puts "Terminating..."
153
153
  @running = false
154
154
  end
@@ -2,22 +2,23 @@ require 'fileutils'
2
2
 
3
3
  module Bluepill
4
4
  class Controller
5
- attr_accessor :base_dir, :log_file, :sockets_dir, :pids_dir
6
-
5
+ attr_accessor :base_dir, :log_file, :sockets_dir, :pids_dir, :timeout
6
+
7
7
  def initialize(options = {})
8
8
  self.log_file = options[:log_file]
9
9
  self.base_dir = options[:base_dir]
10
+ self.timeout = options[:timeout]
10
11
  self.sockets_dir = File.join(base_dir, 'socks')
11
12
  self.pids_dir = File.join(base_dir, 'pids')
12
-
13
+
13
14
  setup_dir_structure
14
15
  cleanup_bluepill_directory
15
16
  end
16
-
17
+
17
18
  def running_applications
18
19
  Dir[File.join(sockets_dir, "*.sock")].map{|x| File.basename(x, ".sock")}
19
20
  end
20
-
21
+
21
22
  def handle_command(application, command, *args)
22
23
  case command.to_sym
23
24
  when :status
@@ -44,10 +45,10 @@ module Bluepill
44
45
  when :log
45
46
  log_file_location = self.send_to_daemon(application, :log_file)
46
47
  log_file_location = self.log_file if log_file_location.to_s.strip.empty?
47
-
48
+
48
49
  requested_pattern = args.first
49
50
  grep_pattern = self.grep_pattern(application, requested_pattern)
50
-
51
+
51
52
  tail = "tail -n 100 -f #{log_file_location} | grep -E '#{grep_pattern}'"
52
53
  puts "Tailing log for #{requested_pattern}..."
53
54
  Kernel.exec(tail)
@@ -56,13 +57,13 @@ module Bluepill
56
57
  exit(1)
57
58
  end
58
59
  end
59
-
60
+
60
61
  def send_to_daemon(application, command, *args)
61
62
  begin
62
63
  verify_version!(application)
63
64
 
64
65
  command = ([command, *args]).join(":")
65
- response = Socket.client_command(base_dir, application, command)
66
+ response = Socket.client_command(base_dir, application, command, timeout)
66
67
  if response.is_a?(Exception)
67
68
  $stderr.puts "Received error from server:"
68
69
  $stderr.puts response.inspect
@@ -76,13 +77,13 @@ module Bluepill
76
77
  abort("Connection Refused: Server is not running")
77
78
  end
78
79
  end
79
-
80
+
80
81
  def grep_pattern(application, query = nil)
81
82
  pattern = [application, query].compact.join(':')
82
83
  ['\[.*', Regexp.escape(pattern), '.*'].compact.join
83
84
  end
84
85
  private
85
-
86
+
86
87
  def cleanup_bluepill_directory
87
88
  self.running_applications.each do |app|
88
89
  pid = pid_for(app)
@@ -94,21 +95,21 @@ module Bluepill
94
95
  end
95
96
  end
96
97
  end
97
-
98
+
98
99
  def pid_for(app)
99
100
  pid_file = File.join(self.pids_dir, "#{app}.pid")
100
101
  File.exists?(pid_file) && File.read(pid_file).to_i
101
102
  end
102
-
103
+
103
104
  def setup_dir_structure
104
105
  [@sockets_dir, @pids_dir].each do |dir|
105
106
  FileUtils.mkdir_p(dir) unless File.exists?(dir)
106
107
  end
107
108
  end
108
-
109
+
109
110
  def verify_version!(application)
110
111
  begin
111
- version = Socket.client_command(base_dir, application, "version")
112
+ version = Socket.client_command(base_dir, application, "version", timeout)
112
113
  if version != Bluepill::VERSION
113
114
  abort("The running version of your daemon seems to be out of date.\nDaemon Version: #{version}, CLI Version: #{Bluepill::VERSION}")
114
115
  end
@@ -382,10 +382,12 @@ module Bluepill
382
382
  def deep_copy
383
383
  # TODO: This is a kludge. Ideally, process templates
384
384
  # would be facotries, and not a template object.
385
- mutex, @event_mutex = @event_mutex, nil
385
+ mutex, triggers, @event_mutex, @triggers = @event_mutex, @triggers, nil, nil
386
386
  clone = Marshal.load(Marshal.dump(self))
387
387
  clone.instance_variable_set("@event_mutex", Monitor.new)
388
+ clone.instance_variable_set("@triggers", triggers.collect{ |t| t.deep_copy })
388
389
  @event_mutex = mutex
390
+ @triggers = triggers
389
391
  clone
390
392
  end
391
393
 
@@ -2,9 +2,12 @@ require 'socket'
2
2
 
3
3
  module Bluepill
4
4
  module Socket
5
+ <<<<<<< HEAD
5
6
  TIMEOUT = 10
6
7
  RETRY = 5
7
8
  @@timeout = 0
9
+ =======
10
+ >>>>>>> akzhan
8
11
 
9
12
  extend self
10
13
 
@@ -12,9 +15,13 @@ module Bluepill
12
15
  UNIXSocket.open(socket_path(base_dir, name), &b)
13
16
  end
14
17
 
18
+ <<<<<<< HEAD
15
19
  def client_command(base_dir, name, command)
20
+ =======
21
+ def client_command(base_dir, name, command, timeout)
22
+ >>>>>>> akzhan
16
23
  client(base_dir, name) do |socket|
17
- Timeout.timeout(TIMEOUT) do
24
+ Timeout.timeout(timeout) do
18
25
  socket.puts command
19
26
  Marshal.load(socket)
20
27
  end
@@ -54,3 +61,7 @@ module Bluepill
54
61
  end
55
62
  end
56
63
  end
64
+ <<<<<<< HEAD
65
+ =======
66
+
67
+ >>>>>>> akzhan
@@ -1,4 +1,5 @@
1
1
  require 'etc'
2
+ require "shellwords"
2
3
 
3
4
  module Bluepill
4
5
  # This class represents the system that bluepill is running on.. It's mainly used to memoize
@@ -72,7 +73,7 @@ module Bluepill
72
73
 
73
74
  redirect_io(*options.values_at(:stdin, :stdout, :stderr))
74
75
 
75
- ::Kernel.exec(cmd)
76
+ ::Kernel.exec(*Shellwords.shellwords(cmd))
76
77
  exit
77
78
  end
78
79
 
@@ -136,7 +137,7 @@ module Bluepill
136
137
  cmd_err_write.close
137
138
 
138
139
  # finally, replace grandchild with cmd
139
- ::Kernel.exec(cmd)
140
+ ::Kernel.exec(*Shellwords.shellwords(cmd))
140
141
  }
141
142
 
142
143
  # we do not use these ends of the pipes in the child
@@ -30,12 +30,21 @@ module Bluepill
30
30
  self.process.dispatch!(event, self.class.name.split("::").last)
31
31
  end
32
32
 
33
+ def deep_copy
34
+ # TODO: This is a kludge. Ideally, process templates
35
+ # would be facotries, and not a template object.
36
+ mutex, @mutex = @mutex, nil
37
+ clone = Marshal.load(Marshal.dump(self))
38
+ clone.instance_variable_set("@mutex", Monitor.new)
39
+ @mutex = mutex
40
+ clone
41
+ end
42
+
33
43
  def schedule_event(event, delay)
34
44
  # TODO: maybe wrap this in a ScheduledEvent class with methods like cancel
35
45
  thread = Thread.new(self) do |trigger|
36
46
  begin
37
47
  sleep delay.to_f
38
- trigger.logger.info("Retrying from flapping")
39
48
  trigger.dispatch!(event)
40
49
  trigger.mutex.synchronize do
41
50
  trigger.scheduled_events.delete_if { |_, thread| thread == Thread.current }
@@ -57,4 +66,4 @@ module Bluepill
57
66
  end
58
67
 
59
68
  end
60
- end
69
+ end
@@ -43,11 +43,9 @@ module Bluepill
43
43
  if duration
44
44
  self.logger.info "Flapping detected: retrying in #{self.retry_in} seconds"
45
45
 
46
- self.schedule_event(:start, self.retry_in)
47
-
48
- # this happens in the process' thread so we don't have to worry about concurrency issues with this event
49
- self.dispatch!(:unmonitor)
50
-
46
+ self.schedule_event(:start, self.retry_in) unless self.retry_in == 0 # retry_in zero means "do not retry, ever"
47
+ self.schedule_event(:unmonitor, 0)
48
+
51
49
  @timeline.clear
52
50
 
53
51
  # This will prevent a transition from happening in the process state_machine
@@ -56,4 +54,4 @@ module Bluepill
56
54
  end
57
55
  end
58
56
  end
59
- end
57
+ end
data/ra-bluepill.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ra-bluepill}
8
- s.version = "0.0.44"
8
+ s.version = "0.0.45"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ra-bluepill
3
3
  version: !ruby/object:Gem::Version
4
- hash: 71
4
+ hash: 69
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 44
10
- version: 0.0.44
9
+ - 45
10
+ version: 0.0.45
11
11
  platform: ruby
12
12
  authors:
13
13
  - Arya Asemanfar