ref: refs/heads/backgroud_patches_bnc550934
commit a1c7d511a32fa2793e50d3ed4addb54574d26ca4
Author: Ladislav Slezak
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 e34815d..1bcdabe 100644
--- a/plugins/status/lib/status.rb
+++ b/plugins/status/lib/status.rb
@@ -10,7 +10,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]
@@ -141,23 +152,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|
@@ -167,6 +254,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