Class: PumaPlus::WorkerThread

Inherits:
Object
  • Object
show all
Defined in:
lib/puma_plus/worker_thread.rb

Overview

One Ruby thread serving one connection to the Go server.

This replaces the seam puma occupies with Server#process_client plus Response#handle_request. There is no thread pool and no reactor: the thread dials in, blocks on read, serves one request, and blocks again. Because the connection carries exactly one request at a time, nothing here needs a mutex or a demultiplexer.

An idle connection is the capacity signal the Go dispatcher counts, so "blocked in read" and "available" are the same state -- there is no separate bookkeeping to drift out of sync.

Defined Under Namespace

Classes: ChunkWriter, Hijack

Constant Summary collapse

MONOTONIC =
Process::CLOCK_MONOTONIC
THREAD_CPU =
Process::CLOCK_THREAD_CPUTIME_ID

Instance Method Summary collapse

Constructor Details

#initialize(socket_path:, app:, worker_id:, thread_index:, multithread: true, multiprocess: false, logger: $stderr) ⇒ WorkerThread

Returns a new instance of WorkerThread.



25
26
27
28
29
30
31
32
33
# File 'lib/puma_plus/worker_thread.rb', line 25

def initialize(socket_path:, app:, worker_id:, thread_index:,
               multithread: true, multiprocess: false, logger: $stderr)
  @socket_path = socket_path
  @app = app
  @worker_id = worker_id
  @thread_index = thread_index
  @logger = logger
  @env_builder = RackEnv.new(multithread: multithread, multiprocess: multiprocess)
end

Instance Method Details

#runObject



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

def run
  conn = UNIXSocket.new(@socket_path)
  conn.sync = true
  hello(conn)

  loop do
    begin
      type, payload = Wire.read_frame(conn)
    rescue Wire::Closed
      break
    end

    case type
    when Wire::REQUEST
      break if serve(conn, payload) == :hijacked
    when Wire::GOAWAY
      # Sent only to an idle conn, so there is never in-flight work to lose.
      break
    else
      @logger.puts "[puma-plus] unexpected frame #{Wire.type_name(type)}; closing"
      break
    end
  end
rescue Errno::ECONNRESET, Errno::EPIPE => e
  @logger.puts "[puma-plus] worker #{@worker_id}/#{@thread_index} lost the server: #{e.class}"
ensure
  conn&.close
end