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 +4 -4
- data/CHANGELOG.md +4 -0
- data/app/cache_processors/concerns/qa_server/cache_keys.rb +0 -5
- data/app/cache_processors/qa_server/cache_expiry_service.rb +5 -0
- data/app/cache_processors/qa_server/job_id_cache.rb +29 -0
- data/app/cache_processors/qa_server/performance_day_graph_cache.rb +27 -0
- data/app/cache_processors/qa_server/performance_month_graph_cache.rb +27 -0
- data/app/cache_processors/qa_server/performance_year_graph_cache.rb +27 -0
- data/app/cache_processors/qa_server/scenario_history_graph_cache.rb +7 -12
- data/app/cache_processors/qa_server/scenario_run_cache.rb +3 -3
- data/app/controllers/qa_server/monitor_status_controller.rb +3 -3
- data/app/jobs/qa_server/history_graph_job.rb +28 -0
- data/app/jobs/qa_server/monitor_tests_job.rb +7 -27
- data/app/jobs/qa_server/performance_day_graph_job.rb +45 -0
- data/app/jobs/qa_server/performance_month_graph_job.rb +45 -0
- data/app/jobs/qa_server/performance_year_graph_job.rb +45 -0
- data/app/services/qa_server/performance_graph_data_service.rb +1 -1
- data/app/services/qa_server/performance_graphing_service.rb +3 -3
- data/lib/qa_server/version.rb +1 -1
- metadata +10 -5
- data/app/cache_processors/qa_server/performance_daily_graph_cache.rb +0 -60
- data/app/cache_processors/qa_server/performance_hourly_graph_cache.rb +0 -65
- data/app/cache_processors/qa_server/performance_monthly_graph_cache.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd13388cd52b97f47cbc007512409654b26e4742
|
4
|
+
data.tar.gz: 2e7fd2e75b65e662460c334cb9c87a39bb246e9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc1aff80d3bf495a4dbedc6fdef33ec4e580f38d3e9953048ac5a991e550b807e5a772059a7ef934cada9243506ef48ef717ef973419a8b0bce8b1aae38de480
|
7
|
+
data.tar.gz: aa8a277abc68f7db17bec6653990e5c3476e89d0860f670cf99f846cb82e26b76c187502c7bd059781a9212596184fd97654363b0b8be885cea29c1088fb94c2
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
17
|
-
|
18
|
-
|
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
|
24
|
-
"
|
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(
|
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
|
20
|
-
|
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::
|
75
|
-
QaServer::
|
76
|
-
QaServer::
|
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
|
-
|
14
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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),
|
data/lib/qa_server/version.rb
CHANGED
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.
|
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-
|
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/
|
347
|
-
- app/cache_processors/qa_server/
|
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
|