Created
February 8, 2023 04:09
-
-
Save kuboon/b3df5ff2002b8bcd15ee26a680d7cb02 to your computer and use it in GitHub Desktop.
Revisions
-
kuboon created this gist
Feb 8, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,3 @@ RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.cgi/$1 [QSA,L] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,125 @@ #!/bin/ruby require 'bundler/setup' # Set up gems listed in the Gemfile. require 'drb/drb' require 'logger' require "rack" require 'rack/rewindable_input' module Dispatch RAILS_ENV = 'value_server' DRUBY_URI = "druby://localhost:13142" LOCKFILE = "../tmp/pids/dispatch.pid" LOGGER = Logger.new('../log/dispatch.log') class CGIHandler def initialize(app) @app = app end def call(env, stdin, stdout) env.update(Rack::SCRIPT_NAME => '', # clear "rack.version" => Rack::VERSION, "rack.input" => stdin, "rack.multithread" => false, "rack.multiprocess" => true, "rack.run_once" => true, "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http" ) LOGGER.info "#{DRb.uri} call rack" status, headers, body = @app.call(env) LOGGER.info "#{DRb.uri} status: #{status}" begin stdout.print "Status: #{status}\r\n" send_headers stdout, headers send_body stdout, body ensure body.close if body.respond_to? :close end end private def send_headers(stdout, headers) headers.each { |k, vs| vs.split("\n").each { |v| stdout.print "#{k}: #{v}\r\n" } } stdout.print "\r\n" stdout.flush end def send_body(stdout, body) body.each { |part| stdout.print part.to_str stdout.flush } end end class << self def main spawn_server unless server_alive? $stdin.binmode DRb.start_service cgi_handler = DRbObject.new_with_uri(DRUBY_URI) LOGGER.info "#{DRb.uri} call cgi_handler" cgi_handler.call(ENV.to_h, Rack::RewindableInput.new($stdin), $stdout) LOGGER.info "#{DRb.uri} done" rescue => e puts "Content-Type: text/plain\nStatus: 500\n\n#{e}" puts e.backtrace LOGGER.error ([e] + e.backtrace).join("\n") end private def server_alive? return false unless File.exist?(LOCKFILE) return true if process_alive? File.read(LOCKFILE).to_i File.delete(LOCKFILE) false end def process_alive?(pid) Process.getpgid( pid ) true rescue Errno::ESRCH false end def spawn_server File.open(LOCKFILE, "w") do |f| if f.flock(File::LOCK_EX | File::LOCK_NB) f.puts fork { start_service } sleep 5 else LOGGER.error("lock failed") end end end def start_service $stdout.reopen("/dev/null", "w") $stderr.reopen("/dev/null", "w") LOGGER.info 'starting server..' DRb.start_service(DRUBY_URI, cgi_handler) LOGGER.info 'started server' DRb.thread.join rescue => e LOGGER.error ([e] + e.backtrace).join("\n") end def cgi_handler ENV['RAILS_ENV'] = RAILS_ENV require '../config/environment' CGIHandler.new(Rails.application) end end end Dispatch.main