[yast-commit] <rest-service> master : optionally read system status at background
ref: refs/heads/master commit 469e69ddfdc62389f40b63fbb9d8e83f557f28fb Author: Ladislav Slezak <lslezak@novell.com> Date: Tue Dec 8 18:26:08 2009 +0100 optionally read system status at background --- plugins/patches/app/models/background_status.rb | 2 +- .../status/app/controllers/status_controller.rb | 5 +- plugins/status/lib/status.rb | 92 +++++++++++++++++++- 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/plugins/patches/app/models/background_status.rb b/plugins/patches/app/models/background_status.rb index 23966cf..2625cb6 100644 --- a/plugins/patches/app/models/background_status.rb +++ b/plugins/patches/app/models/background_status.rb @@ -2,7 +2,7 @@ class BackgroundStatus - attr_writer :status, + attr_accessor :status, :progress, :subprogress diff --git a/plugins/status/app/controllers/status_controller.rb b/plugins/status/app/controllers/status_controller.rb index d649e7a..a57fe11 100644 --- a/plugins/status/app/controllers/status_controller.rb +++ b/plugins/status/app/controllers/status_controller.rb @@ -82,10 +82,13 @@ class StatusController < ApplicationController # GET /status/1 # GET /status/1.xml def show + bgr = params['background'] + Rails.logger.info "Reading status in background" if bgr + permission_check("org.opensuse.yast.system.status.read") @status = Status.new stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i) start = params[:start].blank? ? stop - 300 : Time.at(params[:start].to_i) - @status.collect_data(start, stop, params[:data]) + @status.collect_data(start, stop, params[:data], bgr) end end diff --git a/plugins/status/lib/status.rb b/plugins/status/lib/status.rb index 6836fa9..c17bc77 100644 --- a/plugins/status/lib/status.rb +++ b/plugins/status/lib/status.rb @@ -31,7 +31,18 @@ class Status :metrics, :limits + # currently running status requests in background (current states) + @@running = Hash.new + # finished requests (actual results) + @@done = Hash.new + # a mutex which guards access to the shared class variables above + @@mutex = Mutex.new + def to_xml(options = {}) + if @data.class == Hash && @data.size == 1 && @data[:progress].class == BackgroundStatus + return @data[:progress].to_xml + end + xml = options[:builder] ||= Builder::XmlMarkup.new(options) xml.instruct! unless options[:skip_instruct] @@ -166,23 +177,99 @@ class Status def draw_graph(heigth=nil, width=nil) end + # this is a wrapper to collect_data + def collect_data(start=nil, stop=nil, data = %w{cpu memory disk}, background = false) + # background reading doesn't work correctly if class reloading is active + # (static class members are lost between requests) + if background && !Rails.configuration.cache_classes + Rails.logger.info "Class reloading is active, cannot use background thread (set config.cache_classes = true)" + background = false + end + + if background + # background status + bs = nil + key = start.to_i.to_s + '_' + stop.to_i.to_s + '_' + data.to_s + @@mutex.synchronize do + if @@done.has_key?(key) + Rails.logger.debug "Request #{key} is done" + @data = @@done.delete key + @data.delete :progress + return @data + end + + running = @@running[key] + if running + Rails.logger.debug "Request #{key} is already running: #{running.inspect}" + @data = {:progress => running} + return @data + end + + bs = BackgroundStatus.new + @@running[key] = bs + end + + # read the status in a separate thread + Thread.new do + Rails.logger.info '*** Background thread for reading status started...' + res = collect_status_data(start, stop, data, bs) + @@mutex.synchronize do + @@running.delete(key) + @@done[key] = res + end + Rails.logger.info '*** Finishing background status thread' + end + + # return current progress + @data = {:progress => bs} + return @data + else + collect_status_data(start, stop, data) + end + end + # creates several metrics for a defined period - def collect_data(start=nil, stop=nil, data = %w{cpu memory disk}) + def collect_status_data(start=nil, stop=nil, data = %w{cpu memory disk}, progress=nil) + metrics = available_metrics #puts metrics.inspect result = Hash.new if @collectd_running - case data + current_step = 0 if progress + case data when nil, "all", "All" # all metrics + if progress + total_steps = metrics.size + end + metrics.each_pair do |m, n| + if progress + @@mutex.synchronize do + progress.status = m.to_s + progress.progress = 100 * current_step / total_steps + Rails.logger.debug "*** Reading status: #{progress.status}: #{progress.progress}%" + end + end + metrics[m][:rrds].each do |rrdb| result[File.basename(rrdb).chomp('.rrd')] = fetch_metric(rrdb, start, stop) end @data[m] = result result = Hash.new + + current_step += 1 if progress end else # only metrics in data + total_steps = data.size if progress data.each do |d| + if progress + @@mutex.synchronize do + progress.status = d.to_s + progress.progress = 100 * current_step / total_steps + Rails.logger.debug "*** Reading status: #{progress.status}: #{progress.progress}%" + end + end + metrics.each_pair do |m, n| if m.include?(d) metrics[m][:rrds].each do |rrdb| @@ -192,6 +279,7 @@ class Status result = Hash.new end end + current_step += 1 if progress end end end -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
Ladislav Slezak