rails-profiler 0.29.0 → 0.30.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/profiler-toolbar.js +18 -1
  3. data/app/assets/builds/profiler.js +93 -5
  4. data/app/controllers/profiler/api/cluster_controller.rb +35 -0
  5. data/app/controllers/profiler/api/profiles_controller.rb +8 -2
  6. data/app/controllers/profiler/api/slave_proxy_controller.rb +49 -0
  7. data/app/views/layouts/profiler/application.html.erb +3 -0
  8. data/config/routes.rb +10 -0
  9. data/lib/profiler/cluster/master_client.rb +79 -0
  10. data/lib/profiler/cluster/slave_proxy.rb +106 -0
  11. data/lib/profiler/cluster/slave_registry.rb +50 -0
  12. data/lib/profiler/configuration.rb +20 -1
  13. data/lib/profiler/mcp/server.rb +49 -20
  14. data/lib/profiler/mcp/slave_support.rb +23 -0
  15. data/lib/profiler/mcp/tools/analyze_queries.rb +5 -2
  16. data/lib/profiler/mcp/tools/clear_profiles.rb +11 -1
  17. data/lib/profiler/mcp/tools/delete_env_var.rb +7 -0
  18. data/lib/profiler/mcp/tools/explain_query.rb +8 -0
  19. data/lib/profiler/mcp/tools/get_profile_ajax.rb +5 -2
  20. data/lib/profiler/mcp/tools/get_profile_detail.rb +5 -2
  21. data/lib/profiler/mcp/tools/get_profile_dumps.rb +5 -2
  22. data/lib/profiler/mcp/tools/get_profile_http.rb +5 -2
  23. data/lib/profiler/mcp/tools/get_profile_mailers.rb +5 -2
  24. data/lib/profiler/mcp/tools/get_test_profile_detail.rb +5 -2
  25. data/lib/profiler/mcp/tools/list_env_vars.rb +38 -0
  26. data/lib/profiler/mcp/tools/list_slaves.rb +27 -0
  27. data/lib/profiler/mcp/tools/query_console_profiles.rb +4 -1
  28. data/lib/profiler/mcp/tools/query_jobs.rb +4 -1
  29. data/lib/profiler/mcp/tools/query_mailers.rb +4 -1
  30. data/lib/profiler/mcp/tools/query_profiles.rb +4 -1
  31. data/lib/profiler/mcp/tools/query_test_profiles.rb +4 -1
  32. data/lib/profiler/mcp/tools/reset_all_env_vars.rb +8 -1
  33. data/lib/profiler/mcp/tools/reset_env_var.rb +9 -0
  34. data/lib/profiler/mcp/tools/run_tests.rb +41 -0
  35. data/lib/profiler/mcp/tools/set_env_var.rb +7 -0
  36. data/lib/profiler/railtie.rb +11 -0
  37. data/lib/profiler/version.rb +1 -1
  38. data/lib/profiler.rb +7 -0
  39. metadata +8 -1
@@ -1,10 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../slave_support"
4
+
3
5
  module Profiler
4
6
  module MCP
5
7
  module Tools
6
8
  class ResetAllEnvVars
7
- def self.call(_params)
9
+ def self.call(params)
10
+ if (proxy = MCP::SlaveSupport.with_slave_proxy(params))
11
+ proxy.delete_json("/_profiler/api/env_vars/reset_all")
12
+ return [{ type: "text", text: "Reset all ENV overrides on slave '#{params["slave"]}'." }]
13
+ end
14
+
8
15
  overrides = Profiler.env_override_store.all_overrides
9
16
  count = overrides.size
10
17
 
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../slave_support"
4
+
5
+ require "uri"
6
+
3
7
  module Profiler
4
8
  module MCP
5
9
  module Tools
@@ -9,6 +13,11 @@ module Profiler
9
13
 
10
14
  return [{ type: "text", text: "Error: key cannot be blank." }] if key.empty?
11
15
 
16
+ if (proxy = MCP::SlaveSupport.with_slave_proxy(params))
17
+ proxy.delete_json("/_profiler/api/env_vars/reset?key=#{URI.encode_www_form_component(key)}")
18
+ return [{ type: "text", text: "Reset #{key} on slave '#{params["slave"]}'." }]
19
+ end
20
+
12
21
  overrides = Profiler.env_override_store.all_overrides
13
22
  unless overrides.key?(key)
14
23
  return [{ type: "text", text: "No active override for #{key}." }]
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../slave_support"
4
+
3
5
  require_relative "../../test_runner/discovery"
4
6
  require_relative "../../test_runner/run_store"
5
7
  require_relative "../../test_runner/runner"
@@ -13,6 +15,10 @@ module Profiler
13
15
  POLL_TIMEOUT = 10 # seconds per wait_for_output call
14
16
 
15
17
  def self.call(params)
18
+ if (proxy = MCP::SlaveSupport.with_slave_proxy(params))
19
+ return run_on_slave(proxy, params)
20
+ end
21
+
16
22
  files = Array(params["files"])
17
23
  framework = params["framework"]&.to_s
18
24
  timeout_secs = (params["timeout_seconds"] || DEFAULT_TIMEOUT).to_i
@@ -65,6 +71,41 @@ module Profiler
65
71
 
66
72
  private
67
73
 
74
+ def self.run_on_slave(proxy, params)
75
+ files = Array(params["files"])
76
+ framework = params["framework"].to_s
77
+ timeout_secs = (params["timeout_seconds"] || DEFAULT_TIMEOUT).to_i
78
+ max_output = (params["max_output"] || DEFAULT_MAX_OUTPUT).to_i
79
+
80
+ run_data = proxy.post_json("/_profiler/api/test_runner/runs", { files: files, framework: framework.presence || "rspec" })
81
+
82
+ if run_data["error"]
83
+ return [{ type: "text", text: "Error starting tests on slave: #{run_data["error"]}" }]
84
+ end
85
+
86
+ run_id = run_data["id"]
87
+ deadline = Time.now + timeout_secs
88
+ timed_out = false
89
+
90
+ loop do
91
+ break if Time.now > deadline && (timed_out = true)
92
+ run_data = proxy.get_json("/_profiler/api/test_runner/runs/#{run_id}")
93
+ break if %w[completed failed cancelled].include?(run_data["status"])
94
+ sleep 2
95
+ end
96
+
97
+ output = run_data["output_lines"]&.join.to_s
98
+ output = "…(truncated)\n" + output[-(max_output)..] if output.length > max_output
99
+
100
+ text = "# Test Run on slave '#{params["slave"]}' #{timed_out ? "(timed out)" : ""}\n\n"
101
+ text += "| Field | Value |\n|-------|-------|\n"
102
+ text += "| Run ID | `#{run_id}` |\n"
103
+ text += "| Status | **#{run_data["status"]}** |\n"
104
+ text += "| Exit code | #{run_data["exit_code"].inspect} |\n\n"
105
+ text += "## Output\n```\n#{output.strip}\n```"
106
+ [{ type: "text", text: text }]
107
+ end
108
+
68
109
  def self.collect_run_profiles(since)
69
110
  Profiler.storage.list(limit: 500).select do |p|
70
111
  p.profile_type == "test" && p.started_at && p.started_at >= since
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../slave_support"
4
+
3
5
  module Profiler
4
6
  module MCP
5
7
  module Tools
@@ -10,6 +12,11 @@ module Profiler
10
12
 
11
13
  return [{ type: "text", text: "Error: key cannot be blank." }] if key.empty?
12
14
 
15
+ if (proxy = MCP::SlaveSupport.with_slave_proxy(params))
16
+ proxy.patch_json("/_profiler/api/env_vars", { key: key, value: value })
17
+ return [{ type: "text", text: "Set #{key}=#{value} on slave '#{params["slave"]}'" }]
18
+ end
19
+
13
20
  Profiler.env_override_store.set(key, value)
14
21
  ENV[key] = value
15
22
 
@@ -93,6 +93,17 @@ module Profiler
93
93
  end
94
94
  end
95
95
 
96
+ initializer "profiler.start_cluster_client" do
97
+ # Check slave? inside on_load — the app's own initializers (config/initializers/profiler.rb)
98
+ # set master_url AFTER railtie initializers run, so the check must happen after_initialize.
99
+ ActiveSupport.on_load(:after_initialize) do
100
+ next unless Profiler.configuration.enabled && Profiler.configuration.slave?
101
+
102
+ require_relative "cluster/master_client"
103
+ Profiler::Cluster::MasterClient.new.start
104
+ end
105
+ end
106
+
96
107
  console do
97
108
  next unless Profiler.configuration.enabled && Profiler.configuration.track_console
98
109
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.29.0"
4
+ VERSION = "0.30.0"
5
5
  end
data/lib/profiler.rb CHANGED
@@ -29,6 +29,13 @@ module Profiler
29
29
  @env_override_store ||= EnvOverrideStore.new
30
30
  end
31
31
 
32
+ def slave_registry
33
+ @slave_registry ||= begin
34
+ require_relative "profiler/cluster/slave_registry"
35
+ Cluster::SlaveRegistry.new
36
+ end
37
+ end
38
+
32
39
  def enabled?
33
40
  configuration.enabled
34
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.29.0
4
+ version: 0.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy
@@ -107,6 +107,7 @@ files:
107
107
  - app/assets/builds/profiler.css
108
108
  - app/assets/builds/profiler.js
109
109
  - app/controllers/profiler/api/ajax_controller.rb
110
+ - app/controllers/profiler/api/cluster_controller.rb
110
111
  - app/controllers/profiler/api/console_controller.rb
111
112
  - app/controllers/profiler/api/env_vars_controller.rb
112
113
  - app/controllers/profiler/api/events_controller.rb
@@ -115,6 +116,7 @@ files:
115
116
  - app/controllers/profiler/api/jobs_controller.rb
116
117
  - app/controllers/profiler/api/outbound_http_controller.rb
117
118
  - app/controllers/profiler/api/profiles_controller.rb
119
+ - app/controllers/profiler/api/slave_proxy_controller.rb
118
120
  - app/controllers/profiler/api/test_runner_controller.rb
119
121
  - app/controllers/profiler/api/tests_controller.rb
120
122
  - app/controllers/profiler/api/toolbar_controller.rb
@@ -130,6 +132,9 @@ files:
130
132
  - config/routes.rb
131
133
  - exe/profiler-mcp
132
134
  - lib/profiler.rb
135
+ - lib/profiler/cluster/master_client.rb
136
+ - lib/profiler/cluster/slave_proxy.rb
137
+ - lib/profiler/cluster/slave_registry.rb
133
138
  - lib/profiler/collectors/ajax_collector.rb
134
139
  - lib/profiler/collectors/base_collector.rb
135
140
  - lib/profiler/collectors/cache_collector.rb
@@ -172,6 +177,7 @@ files:
172
177
  - lib/profiler/mcp/resources/slow_queries.rb
173
178
  - lib/profiler/mcp/resources/slow_tests.rb
174
179
  - lib/profiler/mcp/server.rb
180
+ - lib/profiler/mcp/slave_support.rb
175
181
  - lib/profiler/mcp/tools/analyze_queries.rb
176
182
  - lib/profiler/mcp/tools/clear_profiles.rb
177
183
  - lib/profiler/mcp/tools/delete_env_var.rb
@@ -183,6 +189,7 @@ files:
183
189
  - lib/profiler/mcp/tools/get_profile_mailers.rb
184
190
  - lib/profiler/mcp/tools/get_test_profile_detail.rb
185
191
  - lib/profiler/mcp/tools/list_env_vars.rb
192
+ - lib/profiler/mcp/tools/list_slaves.rb
186
193
  - lib/profiler/mcp/tools/query_console_profiles.rb
187
194
  - lib/profiler/mcp/tools/query_jobs.rb
188
195
  - lib/profiler/mcp/tools/query_mailers.rb