Class: Hammer::CronWeb

Inherits:
Object
  • Object
show all
Defined in:
lib/hammer/cron_web.rb

Overview

Localhost web UI for Hammer::CronServer. Hand-rolled HTTP on stdlib TCPServer - the gem has no runtime dependencies and the protocol surface needed here is tiny: parse the request line, drain headers, route on verb+path, answer with Connection: close. No keep-alive, no chunked encoding, one short-lived thread per request so a slow client cannot block the scheduler or other viewers.

Routes:

GET  /               jobs table (schedule, last/next run, status)
GET  /job/<path>     log viewer; ?file=1 shows the rotated log
POST /job/<path>/run trigger a manual run, redirect back (303)
GET  /json           live status as JSON, for scripting

Instance Method Summary collapse

Constructor Details

#initialize(server, port:, pass: nil) ⇒ CronWeb

Returns a new instance of CronWeb.



22
23
24
25
26
# File 'lib/hammer/cron_web.rb', line 22

def initialize(server, port:, pass: nil)
  @server = server
  @port   = port
  @pass   = pass && !pass.empty? ? pass : nil
end

Instance Method Details

#bound_portObject

Actual bound port - differs from the requested one only when the caller asked for port 0 (tests grab a free ephemeral port that way).



30
31
32
# File 'lib/hammer/cron_web.rb', line 30

def bound_port
  @tcp&.addr&.fetch(1)
end

#startObject

Bind 127.0.0.1 only - the UI can trigger task runs, it must never listen on a public interface. Returns self so the caller can hold the instance for #stop.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/hammer/cron_web.rb', line 37

def start
  @tcp = TCPServer.new('127.0.0.1', @port)
  @thread = Thread.new do
    loop do
      sock = begin
        @tcp.accept
      rescue IOError, Errno::EBADF
        break   # #stop closed the listener
      end
      Thread.new(sock) do |s|
        begin
          handle(s)
        rescue StandardError
          nil   # a broken client must not take the UI down
        ensure
          s.close rescue nil
        end
      end
    end
  end
  self
rescue Errno::EADDRINUSE
  raise Hammer::Error, "h:cron web ui: port #{@port} is taken - pick another with --port"
end

#stopObject

Closing the listener pops the accept loop out with IOError.



63
64
65
66
# File 'lib/hammer/cron_web.rb', line 63

def stop
  @tcp&.close
  @thread&.join(2)
end