qa_server 7.3.0 → 7.4.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: fd13388cd52b97f47cbc007512409654b26e4742
4
- data.tar.gz: 2e7fd2e75b65e662460c334cb9c87a39bb246e9e
3
+ metadata.gz: 98cc1d63f4dab80fb1135ddbbef562943e596cae
4
+ data.tar.gz: 0e90cb6702c55c536e8d16d9e9d157127f695446
5
5
  SHA512:
6
- metadata.gz: cc1aff80d3bf495a4dbedc6fdef33ec4e580f38d3e9953048ac5a991e550b807e5a772059a7ef934cada9243506ef48ef717ef973419a8b0bce8b1aae38de480
7
- data.tar.gz: aa8a277abc68f7db17bec6653990e5c3476e89d0860f670cf99f846cb82e26b76c187502c7bd059781a9212596184fd97654363b0b8be885cea29c1088fb94c2
6
+ metadata.gz: 650b0109a2a047900a74272b1e1662a4ce90df5ce830bc47c3def63f115019c72c0ec2c757b25064de73de1694914781ea4a5c6fa0088f36da2a1bdaaceaed5d
7
+ data.tar.gz: 476c4f9489b0a0ea99df541ef1d7067c90b5b9555d24f26a122783947c6e9888a419a0a59161fbbdbd97a07210580e0ace2f6b98bfe63b95bec64316ffa58cb8
@@ -1,3 +1,7 @@
1
+ ### 7.4.0 (2020-04-13)
2
+
3
+ * add size and complexity performance statistics (not auto-generated)
4
+
1
5
  ### 7.3.0 (2020-04-08)
2
6
 
3
7
  * move generation of graphs to background jobs
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+ # Job to generate the performance day graph covering the last 24 hours.
3
+ module QaServer
4
+ class PerformancePerByteJob < ApplicationJob
5
+ include QaServer::PerformanceHistoryDataKeys
6
+
7
+ queue_as :default
8
+
9
+ class_attribute :authority_list_class, :data_service
10
+ self.authority_list_class = QaServer::AuthorityListerService
11
+ self.data_service = QaServer::PerformancePerByteDataService
12
+ # self.graphing_service = QaServer::PerformanceGraphingService
13
+
14
+ def perform(n: 10, action: :search, authority_complexity_ratings: {})
15
+ # checking active_job_id? prevents race conditions for long running jobs
16
+ generate_data_for_authorities(n, action, authority_complexity_ratings) if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
17
+ end
18
+
19
+ private
20
+
21
+ def generate_data_for_authorities(n, action, authority_complexity_ratings)
22
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) - GENERATING performance by byte data")
23
+ auths = authority_list_class.authorities_list
24
+ data = if action.nil?
25
+ # generate_data_for_authority(ALL_AUTH, n) # generates data for all authorities
26
+ auths.each_with_object({}) { |authname, hash| hash[authname] = generate_data_for_authority(authname, n) }
27
+ else
28
+ auths.each_with_object({}) { |authname, hash| hash[authname] = { action => generate_data(authname, action, n) } }
29
+ end
30
+ QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) COMPLETED performance by byte data generation")
31
+ QaServer::JobIdCache.reset_job_id(job_key: job_key)
32
+ convert_to_csv(data, authority_complexity_ratings)
33
+ end
34
+
35
+ def generate_data_for_authority(authority_name, n)
36
+ [SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
37
+ hash[action] = generate_data(authority_name, action, n)
38
+ end
39
+ end
40
+
41
+ def generate_data(authority_name, action, n)
42
+ data_service.calculate(authority_name: authority_name, action: action, n: n)
43
+ # graphing_service.generate_day_graph(authority_name: authority_name, action: action, data: data)
44
+ end
45
+
46
+ # @param data [Hash] performance statistics based on size of data
47
+ # @param authority_complexity_ratings [Hash] complexity rating of the extended context included with results
48
+ # @example data
49
+ # { data_raw_bytes_from_source: [16271, 16271],
50
+ # retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
51
+ # retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
52
+ # graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
53
+ # graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
54
+ # normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
55
+ # normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
56
+ # }
57
+ def convert_to_csv(data, authority_complexity_ratings) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
58
+ performance_file = File.new('log/performance.csv', 'w')
59
+ performance_file.write("authority name, complexity_rating, action, size_bytes, ")
60
+ performance_file.write("retrieve_bytes_per_ms, graph_load_bytes_per_ms, normalize_bytes_per_ms, ")
61
+ performance_file.puts("retrieve_ms_per_byte, graph_load_ms_per_byte, normalize_ms_per_byte")
62
+ data.each do |auth_name, auth_data|
63
+ complexity_rating = authority_complexity_ratings.key?(auth_name) ? authority_complexity_ratings[auth_name] : "UNKNOWN"
64
+ auth_data.each do |action, action_data|
65
+ auth_action = "#{auth_name}, #{complexity_rating}, #{action}"
66
+ 0.upto(action_data[:retrieve_bytes_per_ms].size - 1) do |idx|
67
+ performance_file.write(auth_action)
68
+ performance_file.write(", #{action_data[SRC_BYTES][idx]}")
69
+ performance_file.write(", #{action_data[BPMS_RETR][idx]}")
70
+ performance_file.write(", #{action_data[BPMS_GRPH][idx]}")
71
+ performance_file.write(", #{action_data[BPMS_NORM][idx]}")
72
+ performance_file.write(", #{action_data[MSPB_RETR][idx]}")
73
+ performance_file.write(", #{action_data[MSPB_GRPH][idx]}")
74
+ performance_file.puts(", #{action_data[MSPB_NORM][idx]}")
75
+ end
76
+ end
77
+ end
78
+ performance_file.close
79
+ end
80
+
81
+ def job_key
82
+ "QaServer::PerformanceByByteJob--job_id"
83
+ end
84
+ end
85
+ end
@@ -38,5 +38,13 @@ module QaServer
38
38
  HIGH_NORM = :high_normalization_ms
39
39
  HIGH_ACTN = :high_action_request_ms
40
40
  HIGH_FULL = :high_full_request_ms
41
+
42
+ SRC_BYTES = :data_raw_bytes_from_source
43
+ BPMS_RETR = :retrieve_bytes_per_ms
44
+ MSPB_RETR = :retrieve_ms_per_byte
45
+ BPMS_GRPH = :load_graph_bytes_per_ms
46
+ MSPB_GRPH = :load_graph_ms_per_byte
47
+ BPMS_NORM = :normalization_bytes_per_ms
48
+ MSPB_NORM = :normalization_ms_per_byte
41
49
  end
42
50
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+ # This class calculates min, max, average stats for load, normalization, and full request times for a given set of performance records.
3
+ require 'matrix'
4
+ module QaServer
5
+ class PerformancePerByteCalculatorService
6
+ include QaServer::PerformanceHistoryDataKeys
7
+
8
+ TIME = 0
9
+ BYTES = 1
10
+
11
+ attr_reader :n, :stats, :records
12
+
13
+ # @param records [Array <Qa::PerformanceHistory>] set of records used to calculate the statistics
14
+ def initialize(records:, n:)
15
+ @records = records
16
+ @n = n
17
+ @stats = {}
18
+ end
19
+
20
+ # Calculate performance statistics with percentiles. Min is at the 10th percentile. Max is at the 90th percentile.
21
+ # @return [Hash] hash of the statistics
22
+ # @example
23
+ # { data_raw_bytes_from_source: [16271, 16271],
24
+ # retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
25
+ # retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
26
+ # graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
27
+ # graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
28
+ # normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
29
+ # normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
30
+ # }
31
+ def calculate
32
+ extract_bytes
33
+ calculate_retrieve_stats
34
+ calculate_graph_load_stats
35
+ calculate_normalization_stats
36
+ stats
37
+ end
38
+
39
+ private
40
+
41
+ def extract_bytes
42
+ stats[SRC_BYTES] = retrieve_data.count.zero? ? 0 : retrieve_data.map { |d| d[BYTES] }
43
+ end
44
+
45
+ def calculate_retrieve_stats
46
+ stats[BPMS_RETR] = calculate_bytes_per_ms(retrieve_data)
47
+ stats[MSPB_RETR] = calculate_ms_per_byte(retrieve_data)
48
+ end
49
+
50
+ def calculate_graph_load_stats
51
+ stats[BPMS_GRPH] = calculate_bytes_per_ms(graph_load_data)
52
+ stats[MSPB_GRPH] = calculate_ms_per_byte(graph_load_data)
53
+ end
54
+
55
+ def calculate_normalization_stats
56
+ stats[BPMS_NORM] = calculate_bytes_per_ms(norm_data)
57
+ stats[MSPB_NORM] = calculate_ms_per_byte(norm_data)
58
+ end
59
+
60
+ def calculate_bytes_per_ms(data)
61
+ return 0 if data.count.zero?
62
+ return data[0][BYTES] / d[0][TIME] if data.count == 1
63
+ data.map { |d| d[BYTES] / d[TIME] }
64
+ end
65
+
66
+ def calculate_ms_per_byte(data)
67
+ return 0 if data.count.zero?
68
+ return data[0][TIME] / d[0][BYTES] if data.count == 1
69
+ data.map { |d| d[TIME] / d[BYTES] }
70
+ end
71
+
72
+ def data(column)
73
+ records.where.not(column => nil).order(dt_stamp: :desc).limit(n).pluck(column, :size_bytes)
74
+ end
75
+
76
+ def retrieve_data
77
+ @retrieve_data ||= data(:retrieve_time_ms)
78
+ end
79
+
80
+ def graph_load_data
81
+ @graph_data ||= data(:graph_load_time_ms)
82
+ end
83
+
84
+ def norm_data
85
+ @norm_data ||= data(:normalization_time_ms)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ # This class calculates performance stats based on size of data.
3
+ module QaServer
4
+ class PerformancePerByteDataService
5
+ class << self
6
+ include QaServer::PerformanceHistoryDataKeys
7
+
8
+ class_attribute :stats_calculator_class, :performance_data_class
9
+ self.stats_calculator_class = QaServer::PerformancePerByteCalculatorService
10
+ self.performance_data_class = QaServer::PerformanceHistory
11
+
12
+ # Performance data based on size of data.
13
+ # @param authority_name [String] name of an authority
14
+ # @param action [Symbol] :search, :fetch, or :all_actions
15
+ # @param n [Integer] calculate stats for last n records
16
+ # @returns [Hash] performance statistics based on size of data
17
+ # @example returns for n=2
18
+ # { data_raw_bytes_from_source: [16271, 16271],
19
+ # retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
20
+ # retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
21
+ # graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
22
+ # graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
23
+ # normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
24
+ # normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
25
+ # }
26
+ def calculate(authority_name:, action:, n: 10)
27
+ records = records_by(authority_name, action)
28
+ stats_calculator_class.new(records: records, n: n).calculate
29
+ end
30
+
31
+ private
32
+
33
+ def records_by(authority_name, action)
34
+ where_clause = {}
35
+ where_clause[:authority] = authority_name unless authority_name.nil? || authority_name == ALL_AUTH
36
+ where_clause[:action] = action unless action.nil? || action == ALL_ACTIONS
37
+ performance_data_class.where(where_clause)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module QaServer
3
- VERSION = '7.3.0'
3
+ VERSION = '7.4.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.3.0
4
+ version: 7.4.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-04-08 00:00:00.000000000 Z
11
+ date: 2020-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -362,6 +362,7 @@ files:
362
362
  - app/jobs/qa_server/monitor_tests_job.rb
363
363
  - app/jobs/qa_server/performance_day_graph_job.rb
364
364
  - app/jobs/qa_server/performance_month_graph_job.rb
365
+ - app/jobs/qa_server/performance_per_byte_job.rb
365
366
  - app/jobs/qa_server/performance_year_graph_job.rb
366
367
  - app/loggers/qa_server/scenario_logger.rb
367
368
  - app/models/concerns/qa_server/performance_history_data_keys.rb
@@ -398,6 +399,8 @@ files:
398
399
  - app/services/qa_server/performance_datatable_service.rb
399
400
  - app/services/qa_server/performance_graph_data_service.rb
400
401
  - app/services/qa_server/performance_graphing_service.rb
402
+ - app/services/qa_server/performance_per_byte_calculator_service.rb
403
+ - app/services/qa_server/performance_per_byte_data_service.rb
401
404
  - app/services/qa_server/scenarios_loader_service.rb
402
405
  - app/services/qa_server/time_period_service.rb
403
406
  - app/services/qa_server/time_service.rb