qa_server 7.2.1 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a11e25bb0e1f04c1f4d6a9e1970f1cb438fc752
4
- data.tar.gz: 4a97306cce9c2b6dff9a4e417db000a06c79f3e5
3
+ metadata.gz: fd13388cd52b97f47cbc007512409654b26e4742
4
+ data.tar.gz: 2e7fd2e75b65e662460c334cb9c87a39bb246e9e
5
5
  SHA512:
6
- metadata.gz: c8902939fc36473dbbf7979d0166f72d8e05912ad8b1713268cbe9297f9cfe5c0d01f96cb7b248864c6952c9c9430a061702e783eb37b2536bacc318e04ef637
7
- data.tar.gz: f831642e258fa4d658b283151b73d792242f999629febf58f8f82297b0bed98df5641a4cf03158ffcb689c50438e716ef54734d4bac8182a3be7a8c21cde17c6
6
+ metadata.gz: cc1aff80d3bf495a4dbedc6fdef33ec4e580f38d3e9953048ac5a991e550b807e5a772059a7ef934cada9243506ef48ef717ef973419a8b0bce8b1aae38de480
7
+ data.tar.gz: aa8a277abc68f7db17bec6653990e5c3476e89d0860f670cf99f846cb82e26b76c187502c7bd059781a9212596184fd97654363b0b8be885cea29c1088fb94c2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### 7.3.0 (2020-04-08)
2
+
3
+ * move generation of graphs to background jobs
4
+
1
5
  ### 7.2.1 (2020-02-23)
2
6
 
3
7
  * fix graph fails generation when any label is empty string
@@ -2,15 +2,10 @@
2
2
  # This module sets up the keys used to identify data in Rails.cache
3
3
  module QaServer
4
4
  module CacheKeys
5
- SCENARIO_RUN_TEST_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_test_data"
6
5
  SCENARIO_RUN_SUMMARY_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_summary_data"
7
6
  SCENARIO_RUN_FAILURE_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_failure_data"
8
7
  SCENARIO_RUN_HISTORY_DATA_CACHE_KEY = "QaServer--CacheKeys--scenario_run_history_data"
9
- SCENARIO_RUN_HISTORY_GRAPH_CACHE_KEY = "QaServer--CacheKeys--scenario_run_history_graph"
10
8
 
11
9
  PERFORMANCE_DATATABLE_DATA_CACHE_KEY = "QaServer--Cache--performance_datatable_data"
12
- PERFORMANCE_GRAPH_HOURLY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_hourly_data"
13
- PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_daily_data"
14
- PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY = "QaServer--CacheKeys--performance_graph_monthly_data"
15
10
  end
16
11
  end
@@ -8,6 +8,11 @@ module QaServer
8
8
  cache_expires_at - QaServer::TimeService.current_time
9
9
  end
10
10
 
11
+ def end_of_hour_expiry
12
+ ct = QaServer::TimeService.current_time
13
+ ct.end_of_hour - ct
14
+ end
15
+
11
16
  # @param key [String] cache key
12
17
  # @param force [Boolean] if true, forces cache to regenerate by returning true; otherwise, uses cache expiry to determine whether cache has expired
13
18
  # @return [Boolean] true if cache has expired or is being forced to expire
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ # Provide service methods for getting a list of all authorities and scenarios for an authority.
3
+ module QaServer
4
+ class JobIdCache
5
+ class << self
6
+ # Is the passed in job_id the active one for the job_key?
7
+ # @param job_key [String] key unique to the job being run (e.g. "QaServer::Jobs::MonitorTestsJob")
8
+ # @param job_id [String] UUID for job running the tests
9
+ # @param expires_in [ActiveSupport::Duration] This should be at least as long as the expected job run time to avoid multiple instances of the job running at the same time.
10
+ # @note When job completes, call reset_job_id to invalidate the cache
11
+ def active_job_id?(job_key:, job_id:, expires_in: 30.minutes)
12
+ cached_job_id = Rails.cache.fetch(cache_key(job_key), expires_in: expires_in, race_condition_ttl: 5.minutes) { job_id }
13
+ cached_job_id == job_id
14
+ end
15
+
16
+ # Delete cache for job id for the job represented by job_key. Call this when the job completes.
17
+ # @param job_key [String] key unique to the job being run (e.g. "QaServer::Jobs::MonitorTestsJob")
18
+ def reset_job_id(job_key:)
19
+ Rails.cache.delete(cache_key(job_key))
20
+ end
21
+
22
+ private
23
+
24
+ def cache_key(job_key)
25
+ "#{job_key}-job_id"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # Cache the datetime_stamp of the last time the performance day graph was generated. Calls job to generate the graph if expired.
3
+ module QaServer
4
+ class PerformanceDayGraphCache
5
+ class << self
6
+ # Generates graphs for the past 24 hours for :search, :fetch, and :all actions for each authority.
7
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
8
+ def generate_graphs(force: false)
9
+ Rails.cache.fetch(cache_key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
10
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceDayGraphCache) - KICKING OFF PERFORMANCE DAY GRAPH GENERATION (force: #{force})")
11
+ QaServer::PerformanceDayGraphJob.perform_later
12
+ "Graphs generation initiated at #{QaServer::TimeService.current_time}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def cache_key
19
+ "QaServer::PerformanceDayGraphCache.generate_graphs--latest_generation_initiated"
20
+ end
21
+
22
+ def next_expiry
23
+ QaServer::CacheExpiryService.end_of_hour_expiry
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # Cache the datetime_stamp of the last time the performance month graph was generated. Calls job to generate the graph if expired.
3
+ module QaServer
4
+ class PerformanceMonthGraphCache
5
+ class << self
6
+ # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
7
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
8
+ def generate_graphs(force: false)
9
+ Rails.cache.fetch(cache_key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
10
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceMonthGraphCache) - KICKING OFF PERFORMANCE MONTH GRAPH GENERATION (force: #{force})")
11
+ QaServer::PerformanceMonthGraphJob.perform_later
12
+ "Graphs generation initiated at #{QaServer::TimeService.current_time}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def cache_key
19
+ "QaServer::PerformanceMonthGraphCache.generate_graphs--latest_generation_initiated"
20
+ end
21
+
22
+ def next_expiry
23
+ QaServer::CacheExpiryService.cache_expiry
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # Cache the datetime_stamp of the last time the performance year graph was generated. Calls job to generate the graph if expired.
3
+ module QaServer
4
+ class PerformanceYearGraphCache
5
+ class << self
6
+ # Generates graphs for the 12 months for :search, :fetch, and :all actions for each authority.
7
+ # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
8
+ def generate_graphs(force: false)
9
+ Rails.cache.fetch(cache_key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
10
+ QaServer.config.monitor_logger.debug("(QaServer::PerformanceYearGraphCache) - KICKING OFF PERFORMANCE YEAR GRAPH GENERATION (force: #{force})")
11
+ QaServer::PerformanceYearGraphJob.perform_later
12
+ "Graphs generation initiated at #{QaServer::TimeService.current_time}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def cache_key
19
+ "QaServer::PerformanceYearGraphCache.generate_graphs--latest_generation_initiated"
20
+ end
21
+
22
+ def next_expiry
23
+ QaServer::CacheExpiryService.cache_expiry
24
+ end
25
+ end
26
+ end
27
+ end
@@ -2,26 +2,21 @@
2
2
  # Generate graphs for the past 30 days using cached data. Graphs are generated only if the cache has expired.
3
3
  module QaServer
4
4
  class ScenarioHistoryGraphCache
5
- class_attribute :graphing_service
6
- self.graphing_service = QaServer::HistoryGraphingService
7
-
8
5
  class << self
9
- include QaServer::CacheKeys
10
-
11
- HISTORICAL_GRAPH_FILENAME = 'historical_side_stacked_bar.png'
12
-
13
6
  # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
14
7
  # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
15
8
  def generate_graph(data:, force: false)
16
- return unless QaServer::CacheExpiryService.cache_expired?(key: cache_key_for_force, force: force, next_expiry: next_expiry)
17
- QaServer.config.monitor_logger.debug("(QaServer::ScenarioHistoryGraphCache) - GENERATING historical summary graph (force: #{force})")
18
- graphing_service.generate_graph(data)
9
+ Rails.cache.fetch(cache_key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
10
+ QaServer.config.monitor_logger.debug("(QaServer::ScenarioHistoryGraphCache) - KICKING OFF HISTORY GRAPH GENERATION (force: #{force})")
11
+ QaServer::HistoryGraphJob.perform_later(data: data)
12
+ "Graph generation initiated at #{QaServer::TimeService.current_time}"
13
+ end
19
14
  end
20
15
 
21
16
  private
22
17
 
23
- def cache_key_for_force
24
- "#{SCENARIO_RUN_HISTORY_GRAPH_CACHE_KEY}--force"
18
+ def cache_key
19
+ "QaServer::ScenarioHistoryGraphCache.generate_graph--latest_generation_initiated"
25
20
  end
26
21
 
27
22
  def next_expiry
@@ -7,7 +7,7 @@ module QaServer
7
7
 
8
8
  # Run connection tests
9
9
  def run_tests(force: false)
10
- Rails.cache.fetch(cache_key_for_running_tests, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
10
+ Rails.cache.fetch(cache_key, expires_in: next_expiry, race_condition_ttl: 30.seconds, force: force) do
11
11
  QaServer.config.monitor_logger.debug("(QaServer::ScenarioRunCache) - KICKING OFF TEST RUN (force: #{force})")
12
12
  QaServer::MonitorTestsJob.perform_later
13
13
  "Test run initiated at #{QaServer::TimeService.current_time}"
@@ -16,8 +16,8 @@ module QaServer
16
16
 
17
17
  private
18
18
 
19
- def cache_key_for_running_tests
20
- SCENARIO_RUN_TEST_DATA_CACHE_KEY
19
+ def cache_key
20
+ "QaServer::ScenarioRunCache.run_tests--latest_run_initiated"
21
21
  end
22
22
 
23
23
  def next_expiry
@@ -71,9 +71,9 @@ module QaServer
71
71
 
72
72
  def update_performance_graphs
73
73
  return unless QaServer.config.display_performance_graph?
74
- QaServer::PerformanceHourlyGraphCache.generate_graphs(force: refresh_performance_graphs?)
75
- QaServer::PerformanceDailyGraphCache.generate_graphs(force: refresh_performance_graphs?)
76
- QaServer::PerformanceMonthlyGraphCache.generate_graphs(force: refresh_performance_graphs?)
74
+ QaServer::PerformanceDayGraphCache.generate_graphs(force: refresh_performance_graphs?)
75
+ QaServer::PerformanceMonthGraphCache.generate_graphs(force: refresh_performance_graphs?)
76
+ QaServer::PerformanceYearGraphCache.generate_graphs(force: refresh_performance_graphs?)
77
77
  end
78
78
 
79
79
  def refresh?
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ # Job to generate the graph of historical test runs per authority.
3
+ module QaServer
4
+ class HistoryGraphJob < ApplicationJob
5
+ queue_as :default
6
+
7
+ class_attribute :graphing_service
8
+ self.graphing_service = QaServer::HistoryGraphingService
9
+
10
+ def perform(data:)
11
+ # checking active_job_id? prevents race conditions for long running jobs
12
+ generate_graph(data) if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
13
+ end
14
+
15
+ private
16
+
17
+ def generate_graph(data)
18
+ QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}-#{job_id}) - GENERATING historical summary graph")
19
+ graphing_service.generate_graph(data)
20
+ QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}-#{job_id}) COMPLETED historical summary graph generation")
21
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
22
+ end
23
+
24
+ def job_key
25
+ "QaServer::HistoryGraphJob--job_id"
26
+ end
27
+ end
28
+ end
@@ -10,12 +10,8 @@ module QaServer
10
10
  self.scenario_run_registry_class = QaServer::ScenarioRunRegistry
11
11
 
12
12
  def perform
13
- Rails.cache.fetch("QaServer::MonitorStatusController/latest_test_run_from_cache", expires_in: QaServer::CacheExpiryService.cache_expiry, race_condition_ttl: 5.minutes, force: true) do
14
- job_id = SecureRandom.uuid
15
- monitor_tests_job_id = job_id unless monitor_tests_job_id
16
- run_tests if monitor_tests_job_id == job_id # avoid race conditions
17
- scenario_run_registry_class.latest_run
18
- end
13
+ # checking active_job_id? prevents race conditions for long running jobs
14
+ run_tests if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id, expires_in: 2.hours)
19
15
  end
20
16
 
21
17
  private
@@ -27,32 +23,16 @@ module QaServer
27
23
  scenario_run_registry_class.save_run(scenarios_results: status_log.to_a)
28
24
  QaServer.config.monitor_logger.debug("(#{self.class}##{__method__}-#{job_id}) COMPLETED monitoring tests")
29
25
  QaServer.config.performance_cache.write_all # write out cache after completing tests
30
- reset_monitor_tests_job_id
31
- end
32
-
33
- # @return [String, Boolean] Returns job id of the job currently running tests; otherwise, false if tests are not running
34
- def monitor_tests_job_id
35
- Rails.cache.fetch("QaServer:monitor_tests-job_id", expires_in: 2.hours, race_condition_ttl: 5.minutes) { false }
36
- end
37
-
38
- # Set the id of the job that will run the tests.
39
- # @param job_id [String] UUID for job running the tests
40
- def monitor_tests_job_id=(job_id)
41
- # check to see if there is a current job already running tests
42
- current_job_id = Rails.cache.fetch("QaServer:monitor_tests-job_id", expires_in: 2.hours, race_condition_ttl: 5.seconds) { job_id }
43
-
44
- # current_job_id may be false meaning tests are not currently running; in which case, it is ok to force set job_id
45
- Rails.cache.fetch("QaServer:monitor_tests-job_id", expires_in: 2.hours, race_condition_ttl: 30.seconds, force: true) { job_id } unless current_job_id
46
- end
47
-
48
- # Set job id for monitor tests to false indicating that tests are not currently running
49
- def reset_monitor_tests_job_id
50
- Rails.cache.fetch("QaServer:monitor_tests-job_id", expires_in: 2.hours, race_condition_ttl: 30.seconds, force: true) { false }
26
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
51
27
  end
52
28
 
53
29
  def log_results(authorities_list, results)
54
30
  QaServer.config.monitor_logger.warn("(#{self.class}##{__method__}-#{job_id}) authorities_list is empty") if authorities_list&.empty?
55
31
  QaServer.config.monitor_logger.warn("(#{self.class}##{__method__}-#{job_id}) test results are empty") if results&.empty?
56
32
  end
33
+
34
+ def job_key
35
+ "QaServer::MonitorTestsJob--job_id"
36
+ end
57
37
  end
58
38
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ # Job to generate the performance day graph covering the last 24 hours.
3
+ module QaServer
4
+ class PerformanceDayGraphJob < ApplicationJob
5
+ include QaServer::PerformanceHistoryDataKeys
6
+
7
+ queue_as :default
8
+
9
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
10
+ self.authority_list_class = QaServer::AuthorityListerService
11
+ self.graph_data_service = QaServer::PerformanceGraphDataService
12
+ self.graphing_service = QaServer::PerformanceGraphingService
13
+
14
+ def perform
15
+ # checking active_job_id? prevents race conditions for long running jobs
16
+ generate_graphs_for_authorities if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
17
+ end
18
+
19
+ private
20
+
21
+ def generate_graphs_for_authorities
22
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) - GENERATING performance day graph")
23
+ auths = authority_list_class.authorities_list
24
+ generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
25
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
26
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) COMPLETED performance day graph generation")
27
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
28
+ end
29
+
30
+ def generate_graphs_for_authority(authority_name:)
31
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
+ hash[action] = generate_24_hour_graph(authority_name: authority_name, action: action)
33
+ end
34
+ end
35
+
36
+ def generate_24_hour_graph(authority_name:, action:)
37
+ data = graph_data_service.calculate_last_24_hours(authority_name: authority_name, action: action)
38
+ graphing_service.generate_day_graph(authority_name: authority_name, action: action, data: data)
39
+ end
40
+
41
+ def job_key
42
+ "QaServer::PerformanceDayGraphJob--job_id"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ # Job to generate the performance month graph covering the last 30 days.
3
+ module QaServer
4
+ class PerformanceMonthGraphJob < ApplicationJob
5
+ include QaServer::PerformanceHistoryDataKeys
6
+
7
+ queue_as :default
8
+
9
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
10
+ self.authority_list_class = QaServer::AuthorityListerService
11
+ self.graph_data_service = QaServer::PerformanceGraphDataService
12
+ self.graphing_service = QaServer::PerformanceGraphingService
13
+
14
+ def perform
15
+ # checking active_job_id? prevents race conditions for long running jobs
16
+ generate_graphs_for_authorities if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
17
+ end
18
+
19
+ private
20
+
21
+ def generate_graphs_for_authorities
22
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) - GENERATING performance month graph")
23
+ auths = authority_list_class.authorities_list
24
+ generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
25
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
26
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) COMPLETED performance month graph generation")
27
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
28
+ end
29
+
30
+ def generate_graphs_for_authority(authority_name:)
31
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
+ hash[action] = generate_30_day_graph(authority_name: authority_name, action: action)
33
+ end
34
+ end
35
+
36
+ def generate_30_day_graph(authority_name:, action:)
37
+ data = graph_data_service.calculate_last_30_days(authority_name: authority_name, action: action)
38
+ graphing_service.generate_month_graph(authority_name: authority_name, action: action, data: data)
39
+ end
40
+
41
+ def job_key
42
+ "QaServer::PerformanceMonthGraphJob--job_id"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ # Job to generate the performance year graph covering the last 12 months.
3
+ module QaServer
4
+ class PerformanceYearGraphJob < ApplicationJob
5
+ include QaServer::PerformanceHistoryDataKeys
6
+
7
+ queue_as :default
8
+
9
+ class_attribute :authority_list_class, :graph_data_service, :graphing_service
10
+ self.authority_list_class = QaServer::AuthorityListerService
11
+ self.graph_data_service = QaServer::PerformanceGraphDataService
12
+ self.graphing_service = QaServer::PerformanceGraphingService
13
+
14
+ def perform
15
+ # checking active_job_id? prevents race conditions for long running jobs
16
+ generate_graphs_for_authorities if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
17
+ end
18
+
19
+ private
20
+
21
+ def generate_graphs_for_authorities
22
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) - GENERATING performance year graph")
23
+ auths = authority_list_class.authorities_list
24
+ generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
25
+ auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
26
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) COMPLETED performance year graph generation")
27
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
28
+ end
29
+
30
+ def generate_graphs_for_authority(authority_name:)
31
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
+ hash[action] = generate_12_month_graph(authority_name: authority_name, action: action)
33
+ end
34
+ end
35
+
36
+ def generate_12_month_graph(authority_name:, action:)
37
+ data = graph_data_service.calculate_last_12_months(authority_name: authority_name, action: action)
38
+ graphing_service.generate_year_graph(authority_name: authority_name, action: action, data: data)
39
+ end
40
+
41
+ def job_key
42
+ "QaServer::PerformanceYearGraphJob--job_id"
43
+ end
44
+ end
45
+ end
@@ -73,7 +73,7 @@ module QaServer
73
73
  # @param authority_name [String] name of an authority
74
74
  # @param action [Symbol] :search, :fetch, or :all_actions
75
75
  # @param averages [Hash] existing data for each hour
76
- # @returns [Hash] existing hourly data with the last hour updated
76
+ # @returns [Hash] existing day data with the last hour updated
77
77
  # @example returns
78
78
  # { 0: { hour: '1400', stats: { retrieve_avg_ms: 12.3, graph_load_avg_ms: 2.1, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
79
79
  # 1: { hour: '1500', stats: { retrieve_avg_ms: 12.3, graph_load_avg_ms: 2.1, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
@@ -31,7 +31,7 @@ module QaServer
31
31
  # @param action [Symbol] action performed by the request (e.g. :search, :fetch, :all_actions)
32
32
  # @param data [Hash] data to use to generate the graph
33
33
  # @see QaServer::PerformanceGraphDataService.calculate_last_12_months
34
- def generate_monthly_graph(authority_name: ALL_AUTH, action:, data:)
34
+ def generate_year_graph(authority_name: ALL_AUTH, action:, data:)
35
35
  gruff_data = rework_performance_data_for_gruff(data, BY_MONTH)
36
36
  create_gruff_graph(gruff_data,
37
37
  performance_graph_full_path(authority_name, action, FOR_YEAR),
@@ -44,7 +44,7 @@ module QaServer
44
44
  # @param action [Symbol] action performed by the request (e.g. :search, :fetch, :all_actions)
45
45
  # @param data [Hash] data to use to generate the graph
46
46
  # @see QaServer::PerformanceGraphDataService.calculate_last_30_days
47
- def generate_daily_graph(authority_name: ALL_AUTH, action:, data:)
47
+ def generate_month_graph(authority_name: ALL_AUTH, action:, data:)
48
48
  gruff_data = rework_performance_data_for_gruff(data, BY_DAY)
49
49
  create_gruff_graph(gruff_data,
50
50
  performance_graph_full_path(authority_name, action, FOR_MONTH),
@@ -56,7 +56,7 @@ module QaServer
56
56
  # @param action [Symbol] action performed by the request (e.g. :search, :fetch, :all_actions)
57
57
  # @param data [Hash] data to use to generate the graph
58
58
  # @see QaServer::PerformanceGraphDataService.calculate_last_24_hours
59
- def generate_hourly_graph(authority_name: ALL_AUTH, action:, data:)
59
+ def generate_day_graph(authority_name: ALL_AUTH, action:, data:)
60
60
  gruff_data = rework_performance_data_for_gruff(data, BY_HOUR)
61
61
  create_gruff_graph(gruff_data,
62
62
  performance_graph_full_path(authority_name, action, FOR_DAY),
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module QaServer
3
- VERSION = '7.2.1'
3
+ VERSION = '7.3.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qa_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.1
4
+ version: 7.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - E. Lynette Rayle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-23 00:00:00.000000000 Z
11
+ date: 2020-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -340,11 +340,12 @@ files:
340
340
  - app/assets/stylesheets/qa_server/_usage.scss
341
341
  - app/cache_processors/concerns/qa_server/cache_keys.rb
342
342
  - app/cache_processors/qa_server/cache_expiry_service.rb
343
+ - app/cache_processors/qa_server/job_id_cache.rb
343
344
  - app/cache_processors/qa_server/performance_cache.rb
344
- - app/cache_processors/qa_server/performance_daily_graph_cache.rb
345
345
  - app/cache_processors/qa_server/performance_datatable_cache.rb
346
- - app/cache_processors/qa_server/performance_hourly_graph_cache.rb
347
- - app/cache_processors/qa_server/performance_monthly_graph_cache.rb
346
+ - app/cache_processors/qa_server/performance_day_graph_cache.rb
347
+ - app/cache_processors/qa_server/performance_month_graph_cache.rb
348
+ - app/cache_processors/qa_server/performance_year_graph_cache.rb
348
349
  - app/cache_processors/qa_server/scenario_history_cache.rb
349
350
  - app/cache_processors/qa_server/scenario_history_graph_cache.rb
350
351
  - app/cache_processors/qa_server/scenario_run_cache.rb
@@ -357,7 +358,11 @@ files:
357
358
  - app/controllers/qa_server/homepage_controller.rb
358
359
  - app/controllers/qa_server/monitor_status_controller.rb
359
360
  - app/controllers/qa_server/usage_controller.rb
361
+ - app/jobs/qa_server/history_graph_job.rb
360
362
  - app/jobs/qa_server/monitor_tests_job.rb
363
+ - app/jobs/qa_server/performance_day_graph_job.rb
364
+ - app/jobs/qa_server/performance_month_graph_job.rb
365
+ - app/jobs/qa_server/performance_year_graph_job.rb
361
366
  - app/loggers/qa_server/scenario_logger.rb
362
367
  - app/models/concerns/qa_server/performance_history_data_keys.rb
363
368
  - app/models/qa_server/authority_scenario.rb
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
- # Generate graphs for the past 30 days using cached data. Graphs are generated only if the cache has expired.
3
- module QaServer
4
- class PerformanceDailyGraphCache
5
- class_attribute :authority_list_class, :graph_data_service, :graphing_service
6
- self.authority_list_class = QaServer::AuthorityListerService
7
- self.graph_data_service = QaServer::PerformanceGraphDataService
8
- self.graphing_service = QaServer::PerformanceGraphingService
9
-
10
- class << self
11
- include QaServer::CacheKeys
12
- include QaServer::PerformanceHistoryDataKeys
13
-
14
- # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
15
- # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
16
- def generate_graphs(force: false)
17
- return unless QaServer::CacheExpiryService.cache_expired?(key: cache_key_for_force, force: force, next_expiry: next_expiry)
18
- QaServer.config.monitor_logger.debug("(QaServer::PerformanceDailyGraphCache) - GENERATING daily performance graphs (force: #{force})")
19
- generate_graphs_for_authorities
20
- end
21
-
22
- private
23
-
24
- def generate_graphs_for_authorities
25
- auths = authority_list_class.authorities_list
26
- generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
27
- auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
28
- end
29
-
30
- def generate_graphs_for_authority(authority_name:)
31
- [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
- hash[action] = generate_30_day_graph(authority_name: authority_name, action: action)
33
- end
34
- end
35
-
36
- def generate_30_day_graph(authority_name:, action:)
37
- # real expiration or force caught by cache_expired? So if we are here, either the cache has expired
38
- # or force was requested. We still expire the cache and use ttl to catch race conditions.
39
- Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
- expires_in: next_expiry, race_condition_ttl: 1.hour, force: true) do
41
- data = graph_data_service.calculate_last_30_days(authority_name: authority_name, action: action)
42
- graphing_service.generate_daily_graph(authority_name: authority_name, action: action, data: data)
43
- data
44
- end
45
- end
46
-
47
- def cache_key_for_authority_action(authority_name:, action:)
48
- "#{PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
49
- end
50
-
51
- def cache_key_for_force
52
- "#{PERFORMANCE_GRAPH_DAILY_DATA_CACHE_KEY}--force"
53
- end
54
-
55
- def next_expiry
56
- QaServer::CacheExpiryService.cache_expiry
57
- end
58
- end
59
- end
60
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
- # Generate graphs for the past 24 hours using cached data. The last hour of data is always calculated and all graphs
3
- # for are generated.
4
- module QaServer
5
- class PerformanceHourlyGraphCache
6
- class_attribute :authority_list_class, :graph_data_service, :graphing_service
7
- self.authority_list_class = QaServer::AuthorityListerService
8
- self.graph_data_service = QaServer::PerformanceGraphDataService
9
- self.graphing_service = QaServer::PerformanceGraphingService
10
-
11
- class << self
12
- include QaServer::CacheKeys
13
- include QaServer::PerformanceHistoryDataKeys
14
-
15
- # Generates graphs for the past 24 hours for :search, :fetch, and :all actions for each authority.
16
- # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
17
- def generate_graphs(force: false)
18
- QaServer.config.monitor_logger.debug("(QaServer::PerformanceHourlyGraphCache) - GENERATING hourly performance graphs (force: #{force})")
19
- QaServer.config.performance_cache.write_all
20
- generate_graphs_for_authorities(force: force)
21
- end
22
-
23
- private
24
-
25
- def generate_graphs_for_authorities(force:)
26
- auths = authority_list_class.authorities_list
27
- generate_graphs_for_authority(authority_name: ALL_AUTH, force: force) # generates graph for all authorities
28
- auths.each { |authname| generate_graphs_for_authority(authority_name: authname, force: force) }
29
- end
30
-
31
- def generate_graphs_for_authority(authority_name:, force:)
32
- [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
33
- hash[action] = generate_24_hour_graph(authority_name: authority_name, action: action, force: force)
34
- end
35
- end
36
-
37
- def generate_24_hour_graph(authority_name:, action:, force:)
38
- graph_created = false
39
- data = Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
- expires_in: QaServer::TimeService.current_time.end_of_hour - QaServer::TimeService.current_time,
41
- race_condition_ttl: 1.hour, force: force) do
42
- data = graph_data_service.calculate_last_24_hours(authority_name: authority_name, action: action)
43
- graphing_service.generate_hourly_graph(authority_name: authority_name, action: action, data: data)
44
- graph_created = true
45
- data
46
- end
47
- regen_last_hour_and_graph(authority_name: authority_name, action: action, data: data) unless graph_created
48
- end
49
-
50
- def regen_last_hour_and_graph(authority_name:, action:, data:)
51
- Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
52
- expires_in: QaServer::TimeService.current_time.end_of_hour - QaServer::TimeService.current_time,
53
- race_condition_ttl: 1.hour, force: true) do
54
- data = graph_data_service.recalculate_last_hour(authority_name: authority_name, action: action, averages: data)
55
- graphing_service.generate_hourly_graph(authority_name: authority_name, action: action, data: data)
56
- data
57
- end
58
- end
59
-
60
- def cache_key_for_authority_action(authority_name:, action:)
61
- "#{PERFORMANCE_GRAPH_HOURLY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
62
- end
63
- end
64
- end
65
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
- # Generate graphs for the past 12 months using cached data. Graphs are generated only if the cache has expired.
3
- module QaServer
4
- class PerformanceMonthlyGraphCache
5
- class_attribute :authority_list_class, :graph_data_service, :graphing_service
6
- self.authority_list_class = QaServer::AuthorityListerService
7
- self.graph_data_service = QaServer::PerformanceGraphDataService
8
- self.graphing_service = QaServer::PerformanceGraphingService
9
-
10
- class << self
11
- include QaServer::CacheKeys
12
- include QaServer::PerformanceHistoryDataKeys
13
-
14
- # Generates graphs for the past 30 days for :search, :fetch, and :all actions for each authority.
15
- # @param force [Boolean] if true, run the tests even if the cache hasn't expired; otherwise, use cache if not expired
16
- def generate_graphs(force: false)
17
- return unless QaServer::CacheExpiryService.cache_expired?(key: cache_key_for_force, force: force, next_expiry: next_expiry)
18
- QaServer.config.monitor_logger.debug("(QaServer::PerformanceMonthlyGraphCache) - GENERATING monthly performance graphs (force: #{force})")
19
- generate_graphs_for_authorities
20
- end
21
-
22
- private
23
-
24
- def generate_graphs_for_authorities
25
- auths = authority_list_class.authorities_list
26
- generate_graphs_for_authority(authority_name: ALL_AUTH) # generates graph for all authorities
27
- auths.each { |authname| generate_graphs_for_authority(authority_name: authname) }
28
- end
29
-
30
- def generate_graphs_for_authority(authority_name:)
31
- [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
32
- hash[action] = generate_12_month_graph(authority_name: authority_name, action: action)
33
- end
34
- end
35
-
36
- def generate_12_month_graph(authority_name:, action:)
37
- # real expiration or force caught by cache_expired? So if we are here, either the cache has expired
38
- # or force was requested. We still expire the cache and use ttl to catch race conditions.
39
- Rails.cache.fetch(cache_key_for_authority_action(authority_name: authority_name, action: action),
40
- expires_in: next_expiry, race_condition_ttl: 1.hour, force: true) do
41
- data = graph_data_service.calculate_last_12_months(authority_name: authority_name, action: action)
42
- graphing_service.generate_monthly_graph(authority_name: authority_name, action: action, data: data)
43
- data
44
- end
45
- end
46
-
47
- def cache_key_for_authority_action(authority_name:, action:)
48
- "#{PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY}--#{authority_name}--#{action}"
49
- end
50
-
51
- def cache_key_for_force
52
- "#{PERFORMANCE_GRAPH_MONTHLY_DATA_CACHE_KEY}--force"
53
- end
54
-
55
- def next_expiry
56
- QaServer::CacheExpiryService.cache_expiry
57
- end
58
- end
59
- end
60
- end