Class: OpenC3::ScriptStatusModel
- Defined in:
- lib/openc3/models/script_status_model.rb
Constant Summary collapse
- RUNNING_PRIMARY_KEY =
Note: ScriptRunner only has permissions for keys that start with running-script
'running-script'- COMPLETED_PRIMARY_KEY =
'running-script-completed'- SEARCH_FIELDS =
Fields that a search term is matched against (case-insensitive substring)
['name', 'filename', 'username', 'user_full_name', 'state']
Instance Attribute Summary collapse
-
#current_filename ⇒ Object
Returns the value of attribute current_filename.
-
#disconnect ⇒ Object
Returns the value of attribute disconnect.
-
#end_line_no ⇒ Object
Returns the value of attribute end_line_no.
-
#end_time ⇒ Object
Returns the value of attribute end_time.
-
#environment ⇒ Object
Returns the value of attribute environment.
-
#errors ⇒ Object
Returns the value of attribute errors.
-
#filename ⇒ Object
Returns the value of attribute filename.
-
#line_no ⇒ Object
Returns the value of attribute line_no.
-
#log ⇒ Object
Returns the value of attribute log.
-
#pid ⇒ Object
Returns the value of attribute pid.
-
#report ⇒ Object
Returns the value of attribute report.
-
#script_engine ⇒ Object
Returns the value of attribute script_engine.
-
#shard ⇒ Object
Returns the value of attribute shard.
-
#start_line_no ⇒ Object
Returns the value of attribute start_line_no.
-
#start_time ⇒ Object
Returns the value of attribute start_time.
-
#state ⇒ Object
spawning, init, running, paused, waiting, breakpoint, error, crashed, stopped, completed, completed_errors, killed.
-
#suite_runner ⇒ Object
Returns the value of attribute suite_runner.
-
#user_full_name ⇒ Object
Returns the value of attribute user_full_name.
-
#username ⇒ Object
Returns the value of attribute username.
Attributes inherited from Model
#name, #plugin, #scope, #updated_at
Class Method Summary collapse
- .all(scope:, offset: 0, limit: 10, type: "running") ⇒ Object
- .count(scope:, type: "running") ⇒ Object
-
.fetch(primary_key, scope, keys) ⇒ Object
Fetch and parse the hash values for the given keys, preserving their order.
-
.fetch_all(primary_key, scope) ⇒ Object
Fetch and parse every item for the type, in list order (most recent first).
-
.filter_by_search(items, search) ⇒ Object
Select items where any SEARCH_FIELDS value contains the search term (case-insensitive).
-
.get(name:, scope:, type: "auto") ⇒ Object
NOTE: The following three class methods are used by the ModelController and are reimplemented to enable various Model class methods to work.
- .names(scope:, type: "running") ⇒ Object
-
.page(scope:, offset: 0, limit: 10, type: "running", search: nil) ⇒ Object
Return a single page of items along with the total count of matching items.
Instance Method Summary collapse
- #as_json(*a) ⇒ Object
-
#create(update: false, force: false, queued: false) ⇒ Object
Update the Redis hash at primary_key and set the field "name" to the JSON generated via calling as_json.
-
#destroy(queued: false) ⇒ Object
Delete the model from the Store.
- #id ⇒ Object
-
#initialize(name:, state:, shard: 0, filename:, current_filename: nil, line_no: 0, start_line_no: 1, end_line_no: nil, username:, user_full_name:, start_time:, end_time: nil, disconnect: false, environment: nil, suite_runner: nil, errors: nil, pid: nil, log: nil, report: nil, script_engine: nil, updated_at: nil, scope:) ⇒ ScriptStatusModel
constructor
A new instance of ScriptStatusModel.
- #is_complete? ⇒ Boolean
- #update(force: false, queued: false) ⇒ Object
Methods inherited from Model
#check_disable_erb, #deploy, #destroyed?, #diff, filter, find_all_by_plugin, from_json, get_all_models, get_model, handle_config, set, store, store_queued, #undeploy
Constructor Details
#initialize(name:, state:, shard: 0, filename:, current_filename: nil, line_no: 0, start_line_no: 1, end_line_no: nil, username:, user_full_name:, start_time:, end_time: nil, disconnect: false, environment: nil, suite_runner: nil, errors: nil, pid: nil, log: nil, report: nil, script_engine: nil, updated_at: nil, scope:) ⇒ ScriptStatusModel
Returns a new instance of ScriptStatusModel.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/openc3/models/script_status_model.rb', line 145 def initialize( name:, # id state:, # spawning, init, running, paused, waiting, error, breakpoint, crashed, stopped, completed, completed_errors, killed shard: 0, # Future enhancement of script runner shards filename:, # The initial filename current_filename: nil, # The current filename line_no: 0, # The current line number start_line_no: 1, # The line number to start the script at end_line_no: nil, # The line number to end the script at username:, # The username of the person who started the script user_full_name:, # The full name of the person who started the script start_time:, # The time the script started ISO format end_time: nil, # The time the script ended ISO format disconnect: false, environment: nil, suite_runner: nil, errors: nil, pid: nil, log: nil, report: nil, script_engine: nil, updated_at: nil, scope: ) @state = state if is_complete?() super("#{COMPLETED_PRIMARY_KEY}__#{scope}", name: name, updated_at: updated_at, plugin: nil, scope: scope) else super("#{RUNNING_PRIMARY_KEY}__#{scope}", name: name, updated_at: updated_at, plugin: nil, scope: scope) end @shard = shard.to_i @filename = filename @current_filename = current_filename @line_no = line_no @start_line_no = start_line_no @end_line_no = end_line_no @username = username @user_full_name = user_full_name @start_time = start_time @end_time = end_time @disconnect = disconnect @environment = environment @suite_runner = suite_runner @errors = errors @pid = pid @log = log @report = report @script_engine = script_engine end |
Instance Attribute Details
#current_filename ⇒ Object
Returns the value of attribute current_filename.
28 29 30 |
# File 'lib/openc3/models/script_status_model.rb', line 28 def current_filename @current_filename end |
#disconnect ⇒ Object
Returns the value of attribute disconnect.
36 37 38 |
# File 'lib/openc3/models/script_status_model.rb', line 36 def disconnect @disconnect end |
#end_line_no ⇒ Object
Returns the value of attribute end_line_no.
31 32 33 |
# File 'lib/openc3/models/script_status_model.rb', line 31 def end_line_no @end_line_no end |
#end_time ⇒ Object
Returns the value of attribute end_time.
35 36 37 |
# File 'lib/openc3/models/script_status_model.rb', line 35 def end_time @end_time end |
#environment ⇒ Object
Returns the value of attribute environment.
37 38 39 |
# File 'lib/openc3/models/script_status_model.rb', line 37 def environment @environment end |
#errors ⇒ Object
Returns the value of attribute errors.
39 40 41 |
# File 'lib/openc3/models/script_status_model.rb', line 39 def errors @errors end |
#filename ⇒ Object
Returns the value of attribute filename.
27 28 29 |
# File 'lib/openc3/models/script_status_model.rb', line 27 def filename @filename end |
#line_no ⇒ Object
Returns the value of attribute line_no.
29 30 31 |
# File 'lib/openc3/models/script_status_model.rb', line 29 def line_no @line_no end |
#log ⇒ Object
Returns the value of attribute log.
41 42 43 |
# File 'lib/openc3/models/script_status_model.rb', line 41 def log @log end |
#pid ⇒ Object
Returns the value of attribute pid.
40 41 42 |
# File 'lib/openc3/models/script_status_model.rb', line 40 def pid @pid end |
#report ⇒ Object
Returns the value of attribute report.
42 43 44 |
# File 'lib/openc3/models/script_status_model.rb', line 42 def report @report end |
#script_engine ⇒ Object
Returns the value of attribute script_engine.
43 44 45 |
# File 'lib/openc3/models/script_status_model.rb', line 43 def script_engine @script_engine end |
#shard ⇒ Object
Returns the value of attribute shard.
26 27 28 |
# File 'lib/openc3/models/script_status_model.rb', line 26 def shard @shard end |
#start_line_no ⇒ Object
Returns the value of attribute start_line_no.
30 31 32 |
# File 'lib/openc3/models/script_status_model.rb', line 30 def start_line_no @start_line_no end |
#start_time ⇒ Object
Returns the value of attribute start_time.
34 35 36 |
# File 'lib/openc3/models/script_status_model.rb', line 34 def start_time @start_time end |
#state ⇒ Object
spawning, init, running, paused, waiting, breakpoint, error, crashed, stopped, completed, completed_errors, killed
25 26 27 |
# File 'lib/openc3/models/script_status_model.rb', line 25 def state @state end |
#suite_runner ⇒ Object
Returns the value of attribute suite_runner.
38 39 40 |
# File 'lib/openc3/models/script_status_model.rb', line 38 def suite_runner @suite_runner end |
#user_full_name ⇒ Object
Returns the value of attribute user_full_name.
33 34 35 |
# File 'lib/openc3/models/script_status_model.rb', line 33 def user_full_name @user_full_name end |
#username ⇒ Object
Returns the value of attribute username.
32 33 34 |
# File 'lib/openc3/models/script_status_model.rb', line 32 def username @username end |
Class Method Details
.all(scope:, offset: 0, limit: 10, type: "running") ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/openc3/models/script_status_model.rb', line 64 def self.all(scope:, offset: 0, limit: 10, type: "running") primary_key = (type == "running") ? RUNNING_PRIMARY_KEY : COMPLETED_PRIMARY_KEY keys = self.store.zrevrange("#{primary_key}__#{scope}__LIST", offset.to_i, offset.to_i + limit.to_i - 1) return [] if keys.empty? result = self.store.redis_pool.pipelined do keys.each do |key| self.store.hget("#{primary_key}__#{scope}", key) end end result = result.map do |r| if r.nil? nil else JSON.parse(r, allow_nan: true, create_additions: true) end end return result end |
.count(scope:, type: "running") ⇒ Object
84 85 86 87 |
# File 'lib/openc3/models/script_status_model.rb', line 84 def self.count(scope:, type: "running") primary_key = (type == "running") ? RUNNING_PRIMARY_KEY : COMPLETED_PRIMARY_KEY return self.store.zcount("#{primary_key}__#{scope}__LIST", 0, Float::INFINITY) end |
.fetch(primary_key, scope, keys) ⇒ Object
Fetch and parse the hash values for the given keys, preserving their order
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/openc3/models/script_status_model.rb', line 110 def self.fetch(primary_key, scope, keys) result = self.store.redis_pool.pipelined do keys.each do |key| self.store.hget("#{primary_key}__#{scope}", key) end end result.map do |r| # NOTE: create_additions is intentionally omitted here. ScriptStatusModel # records are written via JSON.generate of as_json (plain hashes/arrays/ # primitives) and never contain a "json_class" marker, so create_additions # has nothing to reconstruct. Enabling it disables the parser's fast path # and makes this parse ~3x slower - costly since this runs over every # record when listing/searching. r.nil? ? nil : JSON.parse(r, allow_nan: true) end end |
.fetch_all(primary_key, scope) ⇒ Object
Fetch and parse every item for the type, in list order (most recent first)
128 129 130 131 132 133 |
# File 'lib/openc3/models/script_status_model.rb', line 128 def self.fetch_all(primary_key, scope) keys = self.store.zrevrange("#{primary_key}__#{scope}__LIST", 0, -1) return [] if keys.empty? self.fetch(primary_key, scope, keys).compact end |
.filter_by_search(items, search) ⇒ Object
Select items where any SEARCH_FIELDS value contains the search term (case-insensitive)
136 137 138 139 140 141 142 143 |
# File 'lib/openc3/models/script_status_model.rb', line 136 def self.filter_by_search(items, search) search = search.to_s.downcase items.select do |item| next false if item.nil? SEARCH_FIELDS.any? { |field| item[field].to_s.downcase.include?(search) } end end |
.get(name:, scope:, type: "auto") ⇒ Object
NOTE: The following three class methods are used by the ModelController and are reimplemented to enable various Model class methods to work
47 48 49 50 51 52 53 54 |
# File 'lib/openc3/models/script_status_model.rb', line 47 def self.get(name:, scope:, type: "auto") if type == "auto" or type == "running" # Check for running first running = super("#{RUNNING_PRIMARY_KEY}__#{scope}", name: name) return running if running end return super("#{COMPLETED_PRIMARY_KEY}__#{scope}", name: name) end |
.names(scope:, type: "running") ⇒ Object
56 57 58 59 60 61 62 |
# File 'lib/openc3/models/script_status_model.rb', line 56 def self.names(scope:, type: "running") if type == "running" return super("#{RUNNING_PRIMARY_KEY}__#{scope}") else return super("#{COMPLETED_PRIMARY_KEY}__#{scope}") end end |
.page(scope:, offset: 0, limit: 10, type: "running", search: nil) ⇒ Object
Return a single page of items along with the total count of matching items. When searching, this fetches, parses, and filters the full list only once (instead of doing that work separately for the page and the count). Returns [page_items, total]
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/openc3/models/script_status_model.rb', line 96 def self.page(scope:, offset: 0, limit: 10, type: "running", search: nil) primary_key = (type == "running") ? RUNNING_PRIMARY_KEY : COMPLETED_PRIMARY_KEY if search and !search.to_s.empty? items = self.filter_by_search(self.fetch_all(primary_key, scope), search) return [items[offset.to_i, limit.to_i] || [], items.length] else total = self.store.zcount("#{primary_key}__#{scope}__LIST", 0, Float::INFINITY) keys = self.store.zrevrange("#{primary_key}__#{scope}__LIST", offset.to_i, offset.to_i + limit.to_i - 1) page_items = keys.empty? ? [] : self.fetch(primary_key, scope, keys) return [page_items, total] end end |
Instance Method Details
#as_json(*a) ⇒ Object
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/openc3/models/script_status_model.rb', line 256 def as_json(*a) { 'name' => @name, 'state' => @state, 'shard' => @shard, 'filename' => @filename, 'current_filename' => @current_filename, 'line_no' => @line_no, 'start_line_no' => @start_line_no, 'end_line_no' => @end_line_no, 'username' => @username, 'user_full_name' => @user_full_name, 'start_time' => @start_time, 'end_time' => @end_time, 'disconnect' => @disconnect, 'environment' => @environment, 'suite_runner' => @suite_runner, 'errors' => @errors, 'pid' => @pid, 'log' => @log, 'report' => @report, 'script_engine' => @script_engine, 'updated_at' => @updated_at, 'scope' => @scope } end |
#create(update: false, force: false, queued: false) ⇒ Object
Update the Redis hash at primary_key and set the field "name" to the JSON generated via calling as_json
213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/openc3/models/script_status_model.rb', line 213 def create(update: false, force: false, queued: false) @updated_at = Time.now.utc.to_nsec_from_epoch if queued write_store = self.class.store_queued else write_store = self.class.store end write_store.hset(@primary_key, @name, JSON.generate(self.as_json(), allow_nan: true)) # Also add to ordered set on create write_store.zadd(@primary_key + "__LIST", @name.to_i, @name) if not update end |
#destroy(queued: false) ⇒ Object
Delete the model from the Store
243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/openc3/models/script_status_model.rb', line 243 def destroy(queued: false) @destroyed = true undeploy() if queued write_store = self.class.store_queued else write_store = self.class.store end write_store.hdel(@primary_key, @name) # Also remove from ordered set write_store.zremrangebyscore(@primary_key + "__LIST", @name.to_i, @name.to_i) end |
#id ⇒ Object
22 23 24 |
# File 'lib/openc3/models/script_status_model.rb', line 22 def id return @name end |
#is_complete? ⇒ Boolean
195 196 197 |
# File 'lib/openc3/models/script_status_model.rb', line 195 def is_complete? return (@state == 'completed' or @state == 'completed_errors' or @state == 'stopped' or @state == 'crashed' or @state == 'killed') end |
#update(force: false, queued: false) ⇒ Object
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/openc3/models/script_status_model.rb', line 227 def update(force: false, queued: false) # Magically handle the change from running to completed if is_complete?() and @primary_key == "#{RUNNING_PRIMARY_KEY}__#{@scope}" # Destroy the running key destroy(queued: queued) @destroyed = false # Move to completed @primary_key = "#{COMPLETED_PRIMARY_KEY}__#{@scope}" create(update: false, force: force, queued: queued) else create(update: true, force: force, queued: queued) end end |