Class: Sonar::Connector::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/sonar_connector/controller.rb

Constant Summary collapse

DEFAULT_CONFIG_FILENAME =
File.join("config", "config.json")

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_filename = DEFAULT_CONFIG_FILENAME) ⇒ Controller

Parse the config file and create instances of each connector, parsing their config in turn.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/sonar_connector/controller.rb', line 41

def initialize(config_filename = DEFAULT_CONFIG_FILENAME)
  @config = Sonar::Connector::Config.load config_filename
  @log = Sonar::Connector::Utils.stdout_logger @config

  @connectors = @config.connectors
  @consumer = Sonar::Connector::Consumer.new(self, @config)
  
  @threads = []
  
  @queue = Queue.new
  
  create_startup_dirs_and_files
rescue Sonar::Connector::InvalidConfig => e
  $stderr << ([e.class.to_s, e.message, *e.backtrace].join("\n")) << "\n"
  raise RuntimeError, "Invalid configuration in #{config_filename}: \n #{e.message}"
end

Instance Attribute Details

#configObject (readonly)

instance of Sonar::Connector::Config



24
25
26
# File 'lib/sonar_connector/controller.rb', line 24

def config
  @config
end

#connectorsObject (readonly)

array of instantiated connector instances



16
17
18
# File 'lib/sonar_connector/controller.rb', line 16

def connectors
  @connectors
end

#consumerObject (readonly)

instance of Sonar::Connector::Consumer



20
21
22
# File 'lib/sonar_connector/controller.rb', line 20

def consumer
  @consumer
end

#logObject (readonly)

controller logger



32
33
34
# File 'lib/sonar_connector/controller.rb', line 32

def log
  @log
end

#queueObject (readonly)

single command queue for threads to communicate with the controller



12
13
14
# File 'lib/sonar_connector/controller.rb', line 12

def queue
  @queue
end

#statusObject (readonly)

instance of Sonar::Connector::Status



28
29
30
# File 'lib/sonar_connector/controller.rb', line 28

def status
  @status
end

#threadsObject (readonly)

array of threads



36
37
38
# File 'lib/sonar_connector/controller.rb', line 36

def threads
  @threads
end

Instance Method Details

#prepare_connectorObject



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sonar_connector/controller.rb', line 86

def prepare_connector
  switch_to_log_file
  log_startup_params
  
  connectors.each do |connector|
    log.info "preparing connector '#{connector.name}'"
    connector.prepare(queue)
  end

  log.info "preparing message queue consumer"
  consumer.prepare(queue)
end

#shutdown_lambdaObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/sonar_connector/controller.rb', line 114

def shutdown_lambda
  lambda do
    puts "\nGiving threads 10 seconds to shut down..."
    threads.each{|t| t.raise(ThreadTerminator)}
    begin
      Timeout::timeout(10) { 
        threads.map(&:join)
      }
    rescue Timeout::Error
      puts "...couldn't stop all threads cleanly."
      log.info "Could not cleanly terminate all threads."
      log.close
      exit(1)
    rescue ThreadTerminator
      # ignore it, since it's come from one of the recently-nuked threads.
    rescue Exception => e
      log.debug ["Caught unhandled exception: ",
                 e.class.to_s,
                 e.message,
                 *e.backtrace].join("\n")
    end
    
    puts "...exited cleanly."
    log.info "Terminated all threads cleanly."
    log.close
    exit(0)
  end
end

#startObject



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sonar_connector/controller.rb', line 62

def start
  prepare_connector
  start_threads

  # let the controlling thread go into an endless sleep
  puts "Ctrl-C to stop."
  
  # Standardize shutdown via ctrl-c and SIGTERM (from god)
  trap "SIGINT", shutdown_lambda
  trap "SIGTERM", shutdown_lambda
  
  endless_sleep
end

#start_consoleObject

prepare the connector, start an IRB console, but don’t start any threads



77
78
79
80
81
82
83
84
# File 'lib/sonar_connector/controller.rb', line 77

def start_console
  prepare_connector
  # make the Controller globally visible
  Connector.const_set("CONTROLLER", self)

  require 'irb'
  IRB.start
end

#start_threadsObject

Main framework loop. Fire up one thread per connector, plus the message queue consumer. Then wait for quit signal.



102
103
104
105
106
107
108
109
110
111
# File 'lib/sonar_connector/controller.rb', line 102

def start_threads
  # fire up the connector threads
  connectors.each do |connector|
    log.info "starting connector '#{connector.name}'"
    threads << Thread.new { connector.start }
  end
  
  log.info "starting the message queue consumer"
  threads << Thread.new{ consumer.watch }
end

#switch_to_log_fileObject



58
59
60
# File 'lib/sonar_connector/controller.rb', line 58

def switch_to_log_file
  @log = Sonar::Connector::Utils.disk_logger(config.controller_log_file, config)
end