Class: Bookie::Database::System
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Bookie::Database::System
- Defined in:
- lib/bookie/database/system.rb
Overview
A system on the network
Constant Summary collapse
- SystemConflictError =
Raised when a system’s specifications are different from those of the active system in the database
Class.new(RuntimeError)
Class Method Summary collapse
-
.active ⇒ Object
Finds all systems that are active (i.e. all systems with NULL values for end_time).
-
.by_name(name) ⇒ Object
Filters by name.
-
.by_system_type(sys_type) ⇒ Object
Filters by system type.
-
.by_time_range(time_range) ⇒ Object
Finds all systems whose running intervals overlap the given time range.
-
.find_current(sender, time = nil) ⇒ Object
Finds the current system for a given sender and time.
-
.summary(time_range = nil) ⇒ Object
Produces a summary of all the systems for the given time interval.
Instance Method Summary collapse
-
#decommission(end_time) ⇒ Object
Decommissions the given system, setting its end time to
end_time
.
Class Method Details
.active ⇒ Object
Finds all systems that are active (i.e. all systems with NULL values for end_time)
20 21 22 |
# File 'lib/bookie/database/system.rb', line 20 def self.active where('systems.end_time IS NULL') end |
.by_name(name) ⇒ Object
Filters by name
26 27 28 |
# File 'lib/bookie/database/system.rb', line 26 def self.by_name(name) where('systems.name = ?', name) end |
.by_system_type(sys_type) ⇒ Object
Filters by system type
32 33 34 |
# File 'lib/bookie/database/system.rb', line 32 def self.by_system_type(sys_type) where('systems.system_type_id = ?', sys_type.id) end |
.by_time_range(time_range) ⇒ Object
Finds all systems whose running intervals overlap the given time range
38 39 40 41 42 43 44 45 |
# File 'lib/bookie/database/system.rb', line 38 def self.by_time_range(time_range) if time_range.empty? self.none else time_range = time_range.exclusive where('(? < systems.end_time OR systems.end_time IS NULL) AND systems.start_time < ?', time_range.first, time_range.last) end end |
.find_current(sender, time = nil) ⇒ Object
Finds the current system for a given sender and time
This method also checks that this system’s specifications are the same as those in the database and raises an error if they are different.
This uses Lock#synchronize internally, so it probably should not be called within a transaction block.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/bookie/database/system.rb', line 53 def self.find_current(sender, time = nil) time ||= Time.now config = sender.config system = nil name = config.hostname Lock[:systems].synchronize do system = by_name(config.hostname).where('systems.start_time <= :time AND (:time <= systems.end_time OR systems.end_time IS NULL)', :time => time).first if system mismatch = !(system.cores == config.cores && system.memory == config.memory) mismatch ||= sender.system_type != system.system_type if mismatch raise SystemConflictError.new("The specifications on record for '#{name}' do not match this system's specifications. Please make sure that all previous systems with this hostname have been marked as decommissioned.") end else raise "There is no system with hostname '#{config.hostname}' that was recorded as active at #{time}." end end system end |
.summary(time_range = nil) ⇒ Object
Produces a summary of all the systems for the given time interval
Returns a hash with the following fields:
:num_systems
-
the number of systems that were active in the given interval
:avail_cpu_time
-
the total CPU time available for the interval
:avail_memory_time
-
the total amount of memory-time available (in kilobyte-seconds)
:avail_memory_avg
-
the average amount of memory available (in kilobytes)
To consider: include the start/end times for the summary (especially if they aren’t provided as arguments)?
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 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 142 143 |
# File 'lib/bookie/database/system.rb', line 84 def self.summary(time_range = nil) current_time = Time.now num_systems = 0 avail_cpu_time = 0 avail_memory_time = 0 #Find all the systems within the time range. systems = System if time_range time_range = time_range.exclusive.normalized systems = systems.by_time_range(time_range) end systems.find_each do |system| start_time = system.start_time end_time = system.end_time #Is there a time range constraint? if time_range #If so, trim start_time and end_time to fit within the range. start_time = [start_time, time_range.first].max if end_time end_time = [end_time, time_range.last].min else end_time ||= time_range.last end else end_time ||= current_time end wall_time = end_time.to_i - start_time.to_i num_systems += 1 avail_cpu_time += system.cores * wall_time avail_memory_time += system.memory * wall_time end time_span = 0 if time_range time_span = time_range.last - time_range.first else time_min = System.minimum(:start_time) #Is there actually a minimum start time? #(In other words, are there any systems in the database?) if time_min if System.active.any? time_max = current_time else time_max = System.maximum(:end_time) end time_span = time_max - time_min end end { :num_systems => num_systems, :avail_cpu_time => avail_cpu_time, :avail_memory_time => avail_memory_time, :avail_memory_avg => if time_span == 0 then 0.0 else Float(avail_memory_time) / time_span end, } end |
Instance Method Details
#decommission(end_time) ⇒ Object
Decommissions the given system, setting its end time to end_time
This should be called any time a system is brought down or its specifications are changed.
149 150 151 152 |
# File 'lib/bookie/database/system.rb', line 149 def decommission(end_time) self.end_time = end_time self.save! end |