Class: Tengine::Resource::Watcher

Inherits:
Object
  • Object
show all
Extended by:
Core::MethodTraceable
Defined in:
lib/tengine/resource/watcher.rb

Defined Under Namespace

Classes: ConfigurationError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv = []) ⇒ Watcher

Returns a new instance of Watcher.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/tengine/resource/watcher.rb', line 17

def initialize(argv = [])
  @config = Tengine::Resource::Config::Resource.parse(argv)
  @pid = sprintf("process:%s/%d", ENV["MM_SERVER_NAME"], Process.pid)
  @mq_config = config[:event_queue].to_hash
  @mq_config[:sender] = { :keep_connection => true }
  @daemonize_options = {
    :app_name => 'tengine_resource_watchd',
    :ARGV => [config[:action]],
    :ontop => !config[:process][:daemon],
    # :monitor => true,
    :multiple => true,
    :dir_mode => :normal,
    :dir => File.expand_path(config[:process][:pid_dir]),
  }

  # 必要なディレクトリの生成
  FileUtils.mkdir_p(File.expand_path(config[:process][:pid_dir]))

  Tengine::Core::MethodTraceable.disabled = !config[:verbose]
rescue Exception
  puts "[#{$!.class.name}] #{$!.message}\n  " << $!.backtrace.join("\n  ")
  raise
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



15
16
17
# File 'lib/tengine/resource/watcher.rb', line 15

def config
  @config
end

#pidObject (readonly)

Returns the value of attribute pid.



15
16
17
# File 'lib/tengine/resource/watcher.rb', line 15

def pid
  @pid
end

Instance Method Details

#find_providersObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/tengine/resource/watcher.rb', line 124

def find_providers
  providers = Tengine::Resource::Provider.all
  begin
    result = providers.to_a
    raise ConfigurationError, "no provider found" if result.empty?
    return result
  rescue NameError => e
    raise e unless e.message =~ /uninitialized constant/
    documents = Mongoid.default_session.collections.
      detect{|c| c.name.to_s == Tengine::Resource::Provider.collection_name.to_s}.find
    types = documents.map{|d| d['_type']}
    undefined_type_names = types.select do |t|
      begin
        t.constantize
        false
      rescue Exception
        true
      end
    end
    raise ConfigurationError, "provider class not found: " << undefined_type_names.join(", ")
  end
end

#mq_suiteObject



41
42
43
44
# File 'lib/tengine/resource/watcher.rb', line 41

def mq_suite
  @mq_suite ||= Tengine::Mq::Suite.new(@mq_config)
  Tengine::Event.mq_suite = @mq_suite
end

#run(__file__) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tengine/resource/watcher.rb', line 51

def run(__file__)
  case config[:action].to_sym
  when :start
    start_daemon(__file__)
  when :stop
    stop_daemon(__file__)
  when :restart
    stop_daemon(__file__)
    start_daemon(__file__)
  end
end

#senderObject



46
47
48
49
# File 'lib/tengine/resource/watcher.rb', line 46

def sender
  @sender ||= Tengine::Event::Sender.new(mq_suite)
  Tengine::Event.default_sender = @sender
end

#shutdownObject



117
118
119
120
121
122
# File 'lib/tengine/resource/watcher.rb', line 117

def shutdown
  EM.run do
    EM.cancel_timer @periodic if @periodic
    sender.stop
  end
end

#startObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tengine/resource/watcher.rb', line 76

def start
  @config.setup_loggers
  # observerの登録
  Mongoid.observers = Tengine::Resource::Observer
  Mongoid.instantiate_observers

  Mongoid.configure do |c|
    c.send :load_configuration, @config[:db]
  end

  EM.run do
    sender.wait_for_connection do
      providers = find_providers
      providers.each do |provider|
        provider.retry_on_error = true if provider.respond_to?(:retry_on_error=)
        # polling_intervalが 0 以下の場合は、問い合わせを行わない
        if (polling_interval = provider.polling_interval) > 0
          # 仮想サーバタイプの監視
          provider.synchronize_virtual_server_types
          name = "#{provider.name}@#{self.class}"
          # Tengine::Core::Mutexをnameに対して固有のObjectIdを設定します。
          Tengine::Core::Mutex::Mutex.add_static_bson_objectid(name, provider.id)
          mutex = Tengine::Core::Mutex.new(name, provider.polling_interval)
          @periodic = EM.add_periodic_timer(provider.polling_interval) do
            mutex.synchronize do
              # 物理サーバの監視
              provider.synchronize_physical_servers
              mutex.heartbeat
              # 仮想サーバの監視
              provider.synchronize_virtual_servers
              mutex.heartbeat
              # 仮想サーバイメージの監視
              provider.synchronize_virtual_server_images
            end
          end
        end
      end
    end
  end
end

#start_daemon(__file__) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/tengine/resource/watcher.rb', line 63

def start_daemon(__file__)
  fname = File.basename __file__
  cwd = Dir.getwd
  Daemons.run_proc(fname, @daemonize_options) do
    Dir.chdir(cwd) { self.start }
  end
end

#stop_daemon(__file__) ⇒ Object



71
72
73
74
# File 'lib/tengine/resource/watcher.rb', line 71

def stop_daemon(__file__)
  fname = File.basename __file__
  Daemons.run_proc(fname, @daemonize_options)
end