ra-bluepill 0.0.44 → 0.0.45

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.
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