qa_server 7.2.1 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|