Skip to content

Instantly share code, notes, and snippets.

@mistersourcerer
Created December 6, 2018 15:26
Show Gist options
  • Save mistersourcerer/9dedbe7883fc63dcef899829818d6940 to your computer and use it in GitHub Desktop.
Save mistersourcerer/9dedbe7883fc63dcef899829818d6940 to your computer and use it in GitHub Desktop.
Easy way to visually see what happens if you FORK with(in) a web process/request.
require "pp"
class Router
attr_reader :routes
def initialize
@routes = {}
end
def route(path, &block)
@routes[path] = block
end
def call(env)
uri = URI(env["REQUEST_URI"])
@routes[uri.path].call(env)
end
def matches?(env)
@routes.key? URI(env["REQUEST_URI"]).path
end
end
@shared_memory = []
router = Router.new
router.route "/very/fast" do |env|
[
200,
{"Content-Type" => "text/html"},
["<html><body><strong>OMG! I AM SO FAST!</strong></body></html>"]
]
end
router.route "/fork/this" do |env|
pid = Process.fork do
STDOUT.puts "sorry world, never returning..."
_terminate = false
Signal.trap "QUIT" do
STDOUT.puts "politely asked, happily obeying"
_terminate = true
end
while(true)
sleep 5
STDOUT.puts "OH! Checking interruptions..."
break if _terminate
end
end
STDOUT.puts "#{Process.pid} hijacked by #{pid}..."
STDOUT.puts "FORKER thread is: #{Thread.current}"
@shared_memory << pid
Process.wait pid
[
200,
{"Content-Type" => "text/html"},
["<html><body><strong>NEVAH RETURNING!?!</strong></body></html>"]
]
end
def kill(pid)
STDOUT.puts "search and destroy #{pid}"
STDOUT.puts "Killer thread is: #{Thread.current}"
Process.kill "QUIT", pid.to_i
end
router.route "/kill" do |env|
params = Rack::Request.new(env).params
pid = params["pid"]
if pid.nil? || pid.empty?
STDOUT.puts "killing #{@shared_memory.join(", ")}"
@shared_memory.each { |_pid| kill _pid }
else
kill pid
end
[
200,
{"Content-Type" => "text/html"},
[<<~html
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<strong>I AM A KILLAH! &#x1F480</strong>
</body>
</html>
html
]
]
end
router.route "/" do |_|
[
200,
{"Content-Type" => "text/html"},
[<<~html
<html>
<body>
<strong>
known routes: <br />
#{router.routes.keys.reject { |r| r == "/" }.join "<br />"}
</strong>
</body>
</html>
html
]
]
end
app = proc do |env|
if router.matches? env
router.call env
else
[
500,
{"Content-Type" => "text/html"},
[<<~html
<html>
<body>
<strong style="color:#ff0000">
NO ROUTE FOR #{env["REQUEST_URI"]}
</strong>
</body>
</html>
html
]
]
end
end
run app
gem "rack"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment