class Bookie::Sender
An object that sends data to the database
Attributes
config[R]
Public Class Methods
new(config)
click to toggle source
Creates a new Sender
config
should be an instance of Bookie::Config
.
# File lib/bookie/sender.rb, line 15 def initialize(config) @config = config sys_type = config.system_type require "bookie/senders/#{sys_type}" extend Bookie::Senders.const_get(sys_type.camelize) end
Public Instance Methods
duplicate(job, system)
click to toggle source
Finds the first job that is a duplicate of the provided job
# File lib/bookie/sender.rb, line 127 def duplicate(job, system) system.jobs.where({ :start_time => job.start_time, :wall_time => job.wall_time, :command_name => job.command_name, :cpu_time => job.cpu_time, :memory => job.memory, :exit_code => job.exit_code }).by_user_name(job.user_name).by_group_name(job.group_name).first end
filtered?(job)
click to toggle source
Returns whether a job should be filtered from the results
# File lib/bookie/sender.rb, line 121 def filtered?(job) @config.excluded_users.include?job.user_name end
send_data(filename)
click to toggle source
Sends job data from the given file to the database server
# File lib/bookie/sender.rb, line 24 def send_data(filename) raise IOError.new("File '#{filename}' does not exist.") unless File.exists?(filename) system = nil known_users = {} known_groups = {} time_min, time_max = nil #Grab data from the first job: each_job(filename) do |job| next if filtered?(job) system = Bookie::Database::System.find_current(self, job.end_time) raise "Jobs already exist in the database for '#{filename}'." if duplicate(job, system) time_min = job.start_time time_max = job.end_time break end #If there are no jobs, return. return unless time_min #Send the job data: each_job(filename) do |job| next if filtered?(job) model = job.to_record time_min = (model.start_time < time_min) ? model.start_time : time_min time_max = (model.end_time > time_max) ? model.end_time : time_max #To consider: handle files that don't have jobs sorted by end time? #To consider: this should rarely happen in real life. Remove test? #(This situation can only arise if log files from different versions of the system are concatenated before sending.) if system.end_time && model.end_time > system.end_time system = Database::System.find_current(self, model.end_time) end user = Bookie::Database::User.find_or_create!( job.user_name, Bookie::Database::Group.find_or_create!(job.group_name, known_groups), known_users ) model.system = system model.user = user model.save! end #Clear out the summaries that would have been affected by the new data: clear_summaries(time_min.to_date, time_max.to_date) end
system_type()
click to toggle source
The name of the Bookie::Database::SystemType
that systems using this sender will have
# File lib/bookie/sender.rb, line 114 def system_type @system_type ||= Bookie::Database::SystemType.find_or_create!(system_type_name, memory_stat_type) end
undo_send(filename)
click to toggle source
Undoes a previous send operation
# File lib/bookie/sender.rb, line 75 def undo_send(filename) raise IOError.new("File '#{filename}' does not exist.") unless File.exists?(filename) system = nil time_min, time_max = nil #Grab data from the first job: each_job(filename) do |job| next if filtered?(job) system = Bookie::Database::System.find_current(self, job.end_time) time_min = job.start_time time_max = job.end_time break end return unless time_min each_job(filename) do |job| next if filtered?(job) if system.end_time && job.end_time > system.end_time system = Database::System.find_current(self, job.end_time) end #TODO: optimize this operation? #(It should be possible to delete all of the jobs with end times between those of the first and last jobs of the file (exclusive), #but jobs with end times matching those of the first/last jobs in the file might be from an earlier or later file, not this one. #This assumes that the files all have jobs sorted by end time. model = duplicate(job, system) break unless model time_min = [model.start_time, time_min].min time_max = [model.end_time, time_max].max model.delete end clear_summaries(time_min.to_date, time_max.to_date) end
Private Instance Methods
clear_summaries(date_min, date_max)
click to toggle source
Used internally by send_data
and undo_send
# File lib/bookie/sender.rb, line 139 def clear_summaries(date_min, date_max) #Since joins don't mix with DELETE statements, we have to do this the hard way. #To consider: prune systems by time? system_ids = Database::System.by_name(@config.hostname).pluck(:id) Database::JobSummary.where('job_summaries.system_id in (?)', system_ids).where('date >= ? AND date <= ?', date_min, date_max).delete_all end