Passenger Standalone with debugger and pry
Mat Brown
8
Tech
Tekst piosenki
I'm a big fan of using Passenger in standalone mode for local Rails development. Anecdotally, it just feels faster than thin—maybe it's got something to do with serving static assets from nginx, although I haven't dug into it.
One big downside with Passenger for development, though, is that out of the box you can't just stick a debugger or binding.pry statement in your code and have it pop open the appropriate REPL in the terminal Passenger is running in.
Recently, while setting up a development CLI, I decided to once and for all solve this problem, mostly so my boss would stop making fun of me for having to switch to Thin every time I wanted to use a debugger.
The basic setup is to run remote versions of debugger and pry, which expose the respective REPLs over a socket. Then you fire up a client which connects to the socket in question; these clients are where you actually interact with the debugger or pry session.
But a nice thing about, say, running thin with the debugger on is that it “just works”—when the code hits a breakpoint, the debugger prompt appears right in the window where Thin is running, outputting the logs, etc. Turns out that is not so hard to do with the remote approach, once you sprinkle in some forking action.
Setting up your app for remote debugger and pry
First, we'll need to install a couple of gems. Add these puppies to your Gemfile:
gem 'rack-debug'
gem 'pry-remote'
So far so good. pry-remote uses a separate binding.pry_remote method to initiate a remote pry session, so there's nothing more we need to do for that. rack-debug, on the other hand, runs as a middleware, so we'll need to add it to our chain. We can create a new file config/initializers/rack_debug.rb to handle that:
if Rails.env.development?
Rails.configuration.middleware.use(
Rack::Debug,
:socket_path => Rails.root.join('tmp', 'rack-debug').to_s
)
end
Putting it all in one placeNow we'd like a single executable that starts up passenger, and also starts up the debugger and pry clients in the same terminal. That way, when we hit a breakpoint, the prompt will appear right where we expect it.
The easiest way to do this is just to make a Ruby script that wraps those actions—we can call it script/start_passenger:
#!/usr/bin/env ruby
require 'bundler'
Bundler.setup(:default, :development)
require 'rack-debug/debugger'
require 'pry-remote'
system('rm', '-fv', 'tmp/rack-debug.*')
fork { exec 'bundle', 'exec', 'passenger', 'start' }
fork do
$0 = 'passenger pry'
loop { PryRemote::CLI.new(%w(--wait)).run }
end
fork do
$0 = 'passenger debugger'
loop do
begin
socket_path = File.expand_path('../../tmp/rack-debug', __FILE__)
Debugger.start_unix_socket_client(socket_path)
rescue Errno::ECONNREFUSED, Errno::ENOENT => e
sleep(1)
retry
end
end
end
trap('INT') { Process.waitall; exit }
Process.waitall
Now just make the script executable:
chmod -v a+x script/start_passengerFire up the script, and you should be able to start developing in passenger with no more debugger or pry pain.
Tłumaczenie
Brak
Polecani artyści
Najnowsze teksty piosenek
Sprawdź teksty piosenek i albumy dodane w ciągu ostatnich 7 dni