Skip to content

Commit

Permalink
Local firefox viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
gmcgibbon committed Nov 20, 2024
1 parent 7f474c1 commit 9a9184f
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 27 deletions.
3 changes: 2 additions & 1 deletion lib/app_profiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module Storage
module Viewer
autoload :BaseViewer, "app_profiler/viewer/base_viewer"
autoload :SpeedscopeViewer, "app_profiler/viewer/speedscope_viewer"
autoload :FirefoxViewer, "app_profiler/viewer/firefox_viewer"
autoload :BaseMiddleware, "app_profiler/viewer/base_middleware"
autoload :SpeedscopeRemoteViewer, "app_profiler/viewer/speedscope_remote_viewer"
autoload :FirefoxRemoteViewer, "app_profiler/viewer/firefox_remote_viewer"
Expand Down Expand Up @@ -125,7 +126,7 @@ def stackprof_viewer
end

def vernier_viewer
@@vernier_viewer ||= Viewer::FirefoxRemoteViewer # rubocop:disable Style/ClassVars
@@vernier_viewer ||= Viewer::FirefoxViewer # rubocop:disable Style/ClassVars
end

def profile_sampler_enabled=(value)
Expand Down
35 changes: 35 additions & 0 deletions lib/app_profiler/exec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module AppProfiler
module Exec # :nodoc:
protected

def valid_commands
raise NotImplementedError
end

def ensure_command_valid(command)
unless valid_command?(command)
raise YarnError, "Illegal command: #{command.join(" ")}."
end
end

def valid_command?(command)
valid_commands.any? do |valid_command|
next unless valid_command.size == command.size

valid_command.zip(command).all? do |valid_part, part|
part.match?(valid_part)
end
end
end

def exec(*command, silent: false, environment: {})
ensure_command_valid(command)

if silent
system(environment, *command, out: File::NULL).tap { |return_code| yield unless return_code }
else
system(environment, *command).tap { |return_code| yield unless return_code }
end
end
end
end
77 changes: 77 additions & 0 deletions lib/app_profiler/viewer/firefox_viewer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require "app_profiler/exec"

module AppProfiler
module Viewer
class FirefoxViewer < BaseViewer
include Exec

CHILD_PIDS = []

at_exit { sleep(1) until CHILD_PIDS.none? }

trap("INT") do
CHILD_PIDS.delete_if { |pid| Process.kill("INT", pid) }
sleep(0.5) # Wait for webrick logs
end

class ProfileViewerError < StandardError; end

VALID_COMMANDS = [
["which", "profile-viewer"],
["gem", "install", "profile-viewer"],
["profile-viewer", /.*\.json/],
]
private_constant(:VALID_COMMANDS)

class << self
def view(profile, params = {})
new(profile).view(**params)
end
end

def valid_commands
VALID_COMMANDS
end

def initialize(profile)
super()
@profile = profile
end

def view(_params = {})
profile_viewer(@profile.file.to_s)
end

private

def setup_profile_viewer
exec("which", "profile-viewer", silent: true) do
gem_install("profile_viewer")
end
@profile_viewer_initialized = true
end

def profile_viewer_setup
@profile_viewer_initialized || false
end

def gem_install(gem)
exec("gem", "install", gem) do
raise ProfileViewerError, "Failed to run gem install #{gem}."
end
end

def profile_viewer(path)
setup_profile_viewer unless profile_viewer_setup

CHILD_PIDS << fork do
Bundler.with_unbundled_env do
exec("profile-viewer", path) { AppProfiler.logger.info("Exiting") }
end
end
end
end
end
end
34 changes: 8 additions & 26 deletions lib/app_profiler/yarn/command.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# frozen_string_literal: true

require "app_profiler/exec"

module AppProfiler
module Yarn
module Command
include Exec

class YarnError < StandardError; end

VALID_COMMANDS = [
Expand All @@ -17,6 +21,10 @@ class YarnError < StandardError; end

private_constant(:VALID_COMMANDS)

def valid_commands
VALID_COMMANDS
end

def yarn(command, *options)
setup_yarn unless yarn_setup

Expand All @@ -41,22 +49,6 @@ def yarn_setup=(state)

private

def ensure_command_valid(command)
unless valid_command?(command)
raise YarnError, "Illegal command: #{command.join(" ")}."
end
end

def valid_command?(command)
VALID_COMMANDS.any? do |valid_command|
next unless valid_command.size == command.size

valid_command.zip(command).all? do |valid_part, part|
part.match?(valid_part)
end
end
end

def ensure_yarn_installed
exec("which", "yarn", silent: true) do
raise(
Expand All @@ -73,16 +65,6 @@ def ensure_yarn_installed
def package_json_exists?
AppProfiler.root.join("package.json").exist?
end

def exec(*command, silent: false)
ensure_command_valid(command)

if silent
system(*command, out: File::NULL).tap { |return_code| yield unless return_code }
else
system(*command).tap { |return_code| yield unless return_code }
end
end
end
end
end

0 comments on commit 9a9184f

Please sign in to comment.