libraries/madeleine_service.rb in Pimki-1.7.092 vs libraries/madeleine_service.rb in Pimki-1.8.092

- old
+ new

@@ -1,163 +1,163 @@ -require 'madeleine' -require 'madeleine/automatic' -require 'madeleine/zmarshal' -require 'singleton' -require 'yaml' - -class MadeleineService - include Madeleine::Automatic::Interceptor - - @@storage_path = self.name.downcase + "_storage" - automatic_read_only :snapshot_interval_hours, :take_snapshot, :clean_old_snapshots, - :restart, :request_stop - - class << self - def storage_path - @@storage_path - end - - def storage_path=(storage_path) - @@storage_path = storage_path - end - - def instance - if @system.nil? - @madeleine_server = MadeleineServer.new(self) - @system = @madeleine_server.system - end - @system - end - - def restart - MadeleineServer.delete_storage(self) - @system = nil - instance - end - - def clean_old_snapshots - instance - @madeleine_server.clean_storage(self) - end - - def take_snapshot - instance - @madeleine_server.force_snapshot - end - - def snapshot_interval_hours - instance - @madeleine_server.snapshot_interval.div MadeleineServer::ONE_HOUR rescue 1 - end - - def snapshot_interval_hours= hours - instance - @madeleine_server.snapshot_interval = hours.to_i * MadeleineServer::ONE_HOUR rescue MadeleineServer::ONE_HOUR - end - - def request_stop - instance - @madeleine_server.request_stop - end - - end -end - -require 'fileutils' -class MadeleineServer - - attr_reader :storage_path - attr_accessor :snapshot_interval - - # Clears all the command_log and snapshot files located in the storage directory, so the - # database is essentially dropped and recreated as blank. Used in tests. - def self.delete_storage(service) - if (File.directory?(service.storage_path)) - FileUtils.rm_rf(Dir[service.storage_path + '/*.command_log']) - FileUtils.rm_rf(Dir[service.storage_path + '/*.snapshot']) - else - FileUtils.mkdir_p(service.storage_path) - end - end - - def clean_storage(service) - force_snapshot - command_logs = Dir[service.storage_path + '/*.command_log'] - raise 'Error: existing command_logs after snapshot' unless command_logs.empty? - - snapshots = Dir[service.storage_path + '/*.snapshot'] - FileUtils.rm_rf(snapshots.sort[0..-2]) - end - - - def initialize(service) - @storage_path = service.storage_path - @snapshot_interval = ONE_HOUR - marshaller = Madeleine::ZMarshal.new() - @server = Madeleine::Automatic::AutomaticSnapshotMadeleine.new(service.storage_path, - marshaller) { service.new } - start_snapshot_thread - end - - def system - @server.system - end - - def command_log_present? - not Dir[File.join(File.expand_path(storage_path), '*.command_log')].empty? - end - - def force_snapshot - begin - hours_since_last_snapshot = 0 - @server.take_snapshot - rescue => e - sleep(ONE_MINUTE) - retry - end - end - - - ONE_MINUTE = 60 - ONE_HOUR = ONE_MINUTE * 60 - MAX_INTERVAL_HOURS = 24 * 2 - - def start_snapshot_thread - @snapshot_thread = Thread.new(@server) { - hours_since_last_snapshot = 0 - while not @request_stop - sleep(snapshot_interval) - hours_since_last_snapshot += snapshot_interval.div ONE_HOUR - begin - # Take a snapshot if there is a command log - if command_log_present? or hours_since_last_snapshot > MAX_INTERVAL_HOURS - # 'Taking a Madeleine snapshot' - @server.take_snapshot - hours_since_last_snapshot = 0 - puts "[#{DateTime.now.strftime '%F %T'}] INFO Taking snapshot" - else - puts "[#{DateTime.now.strftime '%F %T'}] INFO Skipping snapshot (no command logs)" - end - rescue => e - # wait for a minute (not to spoof the log with the same error) - # and go back into the loop, to keep trying - sleep(ONE_MINUTE) - retry - end - end - } - end - - def request_stop - begin - @request_stop = true - if @snapshot_thread and @snapshot_thread.alive? - @snapshot_thread.wakeup - @snapshot_thread.join - end - @server.take_snapshot if command_log_present? - rescue => detail - puts detail - end - end - +require 'madeleine' +require 'madeleine/automatic' +require 'madeleine/zmarshal' +require 'singleton' +require 'yaml' + +class MadeleineService + include Madeleine::Automatic::Interceptor + + @@storage_path = self.name.downcase + "_storage" + automatic_read_only :snapshot_interval_hours, :take_snapshot, :clean_old_snapshots, + :restart, :request_stop + + class << self + def storage_path + @@storage_path + end + + def storage_path=(storage_path) + @@storage_path = storage_path + end + + def instance + if @system.nil? + @madeleine_server = MadeleineServer.new(self) + @system = @madeleine_server.system + end + @system + end + + def restart + MadeleineServer.delete_storage(self) + @system = nil + instance + end + + def clean_old_snapshots + instance + @madeleine_server.clean_storage(self) + end + + def take_snapshot + instance + @madeleine_server.force_snapshot + end + + def snapshot_interval_hours + instance + @madeleine_server.snapshot_interval.div MadeleineServer::ONE_HOUR rescue 1 + end + + def snapshot_interval_hours= hours + instance + @madeleine_server.snapshot_interval = hours.to_i * MadeleineServer::ONE_HOUR rescue MadeleineServer::ONE_HOUR + end + + def request_stop + instance + @madeleine_server.request_stop + end + + end +end + +require 'fileutils' +class MadeleineServer + + attr_reader :storage_path + attr_accessor :snapshot_interval + + # Clears all the command_log and snapshot files located in the storage directory, so the + # database is essentially dropped and recreated as blank. Used in tests. + def self.delete_storage(service) + if (File.directory?(service.storage_path)) + FileUtils.rm_rf(Dir[service.storage_path + '/*.command_log']) + FileUtils.rm_rf(Dir[service.storage_path + '/*.snapshot']) + else + FileUtils.mkdir_p(service.storage_path) + end + end + + def clean_storage(service) + force_snapshot + command_logs = Dir[service.storage_path + '/*.command_log'] + raise 'Error: existing command_logs after snapshot' unless command_logs.empty? + + snapshots = Dir[service.storage_path + '/*.snapshot'] + FileUtils.rm_rf(snapshots.sort[0..-2]) + end + + + def initialize(service) + @storage_path = service.storage_path + @snapshot_interval = ONE_HOUR + marshaller = Madeleine::ZMarshal.new() + @server = Madeleine::Automatic::AutomaticSnapshotMadeleine.new(service.storage_path, + marshaller) { service.new } + start_snapshot_thread + end + + def system + @server.system + end + + def command_log_present? + not Dir[File.join(File.expand_path(storage_path), '*.command_log')].empty? + end + + def force_snapshot + begin + hours_since_last_snapshot = 0 + @server.take_snapshot + rescue => e + sleep(ONE_MINUTE) + retry + end + end + + + ONE_MINUTE = 60 + ONE_HOUR = ONE_MINUTE * 60 + MAX_INTERVAL_HOURS = 24 * 2 + + def start_snapshot_thread + @snapshot_thread = Thread.new(@server) { + hours_since_last_snapshot = 0 + while not @request_stop + sleep(snapshot_interval) + hours_since_last_snapshot += snapshot_interval.div ONE_HOUR + begin + # Take a snapshot if there is a command log + if command_log_present? or hours_since_last_snapshot > MAX_INTERVAL_HOURS + # 'Taking a Madeleine snapshot' + @server.take_snapshot + hours_since_last_snapshot = 0 + puts "[#{DateTime.now.strftime '%F %T'}] INFO Taking snapshot" + else + puts "[#{DateTime.now.strftime '%F %T'}] INFO Skipping snapshot (no command logs)" + end + rescue => e + # wait for a minute (not to spoof the log with the same error) + # and go back into the loop, to keep trying + sleep(ONE_MINUTE) + retry + end + end + } + end + + def request_stop + begin + @request_stop = true + if @snapshot_thread and @snapshot_thread.alive? + @snapshot_thread.wakeup + @snapshot_thread.join + end + @server.take_snapshot if command_log_present? + rescue => detail + puts detail + end + end + end \ No newline at end of file