lib/tp2.rb
# frozen_string_literal: true require 'uringmachine' require 'tp2/version' require 'tp2/server' require 'tp2/logger' class UringMachine def puts(str) write_async(1, "#{str}\n") end end module TP2 BANNER = ( "\n" + " ooo\n" + " oo\n" + " o\n" + " \\|/ TP2 - a modern web server for Ruby apps\n" + " / \\ \n" + " / x \\ https://github.com/noteflakes/tp2\n" + "⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\n" ) class << self def run(opts = nil, &app) if @in_run @config = opts if opts @config[:app] = app if app return end opts ||= @config || {} begin @in_run = true machine = opts[:machine] || UM.new machine.puts(opts[:banner]) if opts[:banner] opts[:logger]&.info(message: "Running TP2 #{TP2::VERSION}, UringMachine #{UM::VERSION}, Ruby #{RUBY_VERSION}") server = Server.new(machine, opts, &app) setup_signal_handling(machine, Fiber.current) server.run ensure @in_run = false end end def config(opts = nil, &app) return @config if !opts && !app @config = opts || {} @config[:app] = app if app end private def setup_signal_handling(machine, fiber) queue = UM::Queue.new trap('SIGINT') { machine.push(queue, :SIGINT) } machine.spin { watch_for_int_signal(machine, queue, fiber) } end # waits for signal from queue, then terminates given fiber # to be done def watch_for_int_signal(machine, queue, fiber) machine.shift(queue) machine.schedule(fiber, UM::Terminate.new) end end end