Class: Sonar::Connector::Base
- Inherits:
-
Object
- Object
- Sonar::Connector::Base
- Defined in:
- lib/sonar_connector/connectors/base.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#connector ⇒ Object
readonly
this connector.
-
#connector_dir ⇒ Object
readonly
each connector instance has a working dir for its state and files.
-
#connector_filestore ⇒ Object
readonly
filestore for whole connector.
-
#filestore ⇒ Object
readonly
filestore for an action run.
-
#log ⇒ Object
readonly
logger instance.
-
#name ⇒ Object
readonly
every connector has a unique name.
-
#queue ⇒ Object
readonly
central command queue for sending messages back to the controller.
-
#raw_config ⇒ Object
readonly
Connector-specific config hash.
-
#repeat_delay ⇒ Object
readonly
repeat delay which is waited out on each cycle of the run loop.
-
#run ⇒ Object
readonly
run loop flag.
-
#source_connectors ⇒ Object
readonly
Array of associated connectors that provide source data via the file system.
-
#state ⇒ Object
readonly
state hash that is serialized and persisted to disk every cycle of the run loop.
Instance Method Summary collapse
-
#cleanup ⇒ Object
Cleanup routine after connector shutdown.
-
#initialize(connector_config, base_config) ⇒ Base
constructor
A new instance of Base.
-
#load_state ⇒ Object
Load the state hash from YAML file.
-
#parse(config) ⇒ Object
Connector subclasses can overload the parse method.
- #prepare(queue) ⇒ Object
-
#read_state ⇒ Object
Read state file.
- #run_loop ⇒ Object
- #run_once ⇒ Object
-
#save_state ⇒ Object
Save the state hash to a YAML file.
-
#start ⇒ Object
the main run loop that every connector executes indefinitely until Thread.raise is called on this instance.
-
#switch_to_log_file ⇒ Object
Logging defaults to use STDOUT.
- #to_s ⇒ Object (also: #inspect)
Constructor Details
#initialize(connector_config, base_config) ⇒ Base
Returns a new instance of Base.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/sonar_connector/connectors/base.rb', line 41 def initialize(connector_config, base_config) @base_config = base_config @raw_config = connector_config @name = connector_config["name"] @connector = self # Create STDOUT logger and inherit the logger settings from the base controller config @log_file = File.join base_config.log_dir, "connector_#{@name}.log" @log = Sonar::Connector::Utils.stdout_logger base_config # every connector instance must set the repeat delay raise InvalidConfig.new("Connector '#{@name}': repeat_delay is missing or blank") if connector_config["repeat_delay"].blank? @repeat_delay = connector_config["repeat_delay"].to_i raise InvalidConfig.new("Connector '#{@name}': repeat_delay must be >= 1 second") if @repeat_delay < 1 @connector_dir = File.join(base_config.connectors_dir, @name) FileUtils.mkdir_p(@connector_dir) @state_file = File.join(@connector_dir, "state.yml") # empty state hash which will get written to by parse, and then potentially over-written by load_state @state = {} @connector_filestore = Sonar::Connector::FileStore.new(@connector_dir, "#{@name}_filestore", [:working, :error, :complete, :actions], :logger=>@log) parse connector_config load_state @run = true end |
Instance Attribute Details
#connector ⇒ Object (readonly)
this connector
9 10 11 |
# File 'lib/sonar_connector/connectors/base.rb', line 9 def connector @connector end |
#connector_dir ⇒ Object (readonly)
each connector instance has a working dir for its state and files
15 16 17 |
# File 'lib/sonar_connector/connectors/base.rb', line 15 def connector_dir @connector_dir end |
#connector_filestore ⇒ Object (readonly)
filestore for whole connector
33 34 35 |
# File 'lib/sonar_connector/connectors/base.rb', line 33 def connector_filestore @connector_filestore end |
#filestore ⇒ Object (readonly)
filestore for an action run
36 37 38 |
# File 'lib/sonar_connector/connectors/base.rb', line 36 def filestore @filestore end |
#log ⇒ Object (readonly)
logger instance
18 19 20 |
# File 'lib/sonar_connector/connectors/base.rb', line 18 def log @log end |
#name ⇒ Object (readonly)
every connector has a unique name
6 7 8 |
# File 'lib/sonar_connector/connectors/base.rb', line 6 def name @name end |
#queue ⇒ Object (readonly)
central command queue for sending messages back to the controller
27 28 29 |
# File 'lib/sonar_connector/connectors/base.rb', line 27 def queue @queue end |
#raw_config ⇒ Object (readonly)
Connector-specific config hash
12 13 14 |
# File 'lib/sonar_connector/connectors/base.rb', line 12 def raw_config @raw_config end |
#repeat_delay ⇒ Object (readonly)
repeat delay which is waited out on each cycle of the run loop
24 25 26 |
# File 'lib/sonar_connector/connectors/base.rb', line 24 def repeat_delay @repeat_delay end |
#run ⇒ Object (readonly)
run loop flag
30 31 32 |
# File 'lib/sonar_connector/connectors/base.rb', line 30 def run @run end |
#source_connectors ⇒ Object
Array of associated connectors that provide source data via the file system
39 40 41 |
# File 'lib/sonar_connector/connectors/base.rb', line 39 def source_connectors @source_connectors end |
#state ⇒ Object (readonly)
state hash that is serialized and persisted to disk every cycle of the run loop
21 22 23 |
# File 'lib/sonar_connector/connectors/base.rb', line 21 def state @state end |
Instance Method Details
#cleanup ⇒ Object
Cleanup routine after connector shutdown
116 117 |
# File 'lib/sonar_connector/connectors/base.rb', line 116 def cleanup end |
#load_state ⇒ Object
Load the state hash from YAML file
91 92 93 |
# File 'lib/sonar_connector/connectors/base.rb', line 91 def load_state @state.merge! read_state end |
#parse(config) ⇒ Object
Connector subclasses can overload the parse method.
171 172 173 |
# File 'lib/sonar_connector/connectors/base.rb', line 171 def parse(config) log.warn "Method #parse called on connector base class. Connector #{name} should define #parse method." end |
#prepare(queue) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/sonar_connector/connectors/base.rb', line 75 def prepare(queue) @queue = queue switch_to_log_file cleanup_old_action_filestores # in case we were interrupted mid-action cleanup # before we begin end |
#read_state ⇒ Object
Read state file
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/sonar_connector/connectors/base.rb', line 96 def read_state s = {} if File.exist?(state_file) ds = YAML.load_file state_file raise "State file did not contain a serialised hash." unless ds.is_a?(Hash) s = ds # only return the parsed value if it is actually a hash end rescue Exception => e log.error "Error loading #{state_file} so it was ignored. Original error: #{e.}\n" + e.backtrace.join("\n") ensure return s end |
#run_loop ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/sonar_connector/connectors/base.rb', line 133 def run_loop while run begin run_once sleep_for repeat_delay rescue ThreadTerminator break rescue Exception => e log.error ["Connector '#{name} raised an unhandled exception:", e.class.to_s, e., *e.backtrace].join("\n") log.info "Connector blew up with an exception - waiting 5 seconds before retrying." queue << Sonar::Connector::UpdateStatusCommand.new(connector, 'last_action', Sonar::Connector::ACTION_FAILED) sleep_for 5 end end end |
#run_once ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/sonar_connector/connectors/base.rb', line 152 def run_once log.info "beginning action" with_action_filestore do action save_state log.info "finished action,saved state" log.info "working: #{filestore.count(:working)}, error: #{filestore.count(:error)}, complete: #{filestore.count(:complete)}" queue << Sonar::Connector::UpdateStatusCommand.new(connector, 'last_action', Sonar::Connector::ACTION_OK) queue << Sonar::Connector::UpdateDiskUsageCommand.new(connector) queue << Sonar::Connector::UpdateStatusCommand.new(connector, 'working_count', filestore.count(:working)) queue << Sonar::Connector::UpdateStatusCommand.new(connector, 'error_count', filestore.count(:error)) queue << Sonar::Connector::UpdateStatusCommand.new(connector, 'complete_count', filestore.count(:complete)) end end |
#save_state ⇒ Object
Save the state hash to a YAML file
110 111 112 113 |
# File 'lib/sonar_connector/connectors/base.rb', line 110 def save_state make_dir File.open(state_file, "w"){|f| f << state.to_yaml } end |
#start ⇒ Object
the main run loop that every connector executes indefinitely until Thread.raise is called on this instance.
121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/sonar_connector/connectors/base.rb', line 121 def start begin run_loop @run = false cleanup true rescue Exception=>e log.error([e.class.to_s, e., *e.backtrace].join("\n")) end end |
#switch_to_log_file ⇒ Object
Logging defaults to use STDOUT. After initialization we need to switch the logger to use an output file.
85 86 87 88 |
# File 'lib/sonar_connector/connectors/base.rb', line 85 def switch_to_log_file @log = Sonar::Connector::Utils.disk_logger(log_file, base_config) @connector_filestore.logger = @log if @connector_filestore end |
#to_s ⇒ Object Also known as: inspect
175 176 177 |
# File 'lib/sonar_connector/connectors/base.rb', line 175 def to_s "#{self.class} '#{name}'" end |