Alex's Slip-box

These are my org-mode notes in sort of Zettelkasten style

Puma

:ID: 4ED73BAB-481F-4CFA-9449-EA46446C07DF

# Puma Concurrency and Load Balancing

See also https://github.com/puma/puma/blob/master/docs/architecture.md

graph TD
    A[Client Connections] --> B[Socket Accept Queue]
    B --> C[Shared Listening Socket]
    C --> D1[Worker 1]
    C --> D2[Worker 2]
    C --> D3[Worker 3]
    D1 --> E1[Thread Pool 1]
    D2 --> E2[Thread Pool 2]
    D3 --> E3[Thread Pool 3]
    subgraph Operating System
      B
      C
    end
    subgraph Puma
        D1
        D2
        D3
        E1
        E2
        E3
    end

# Concurrency Model

  • Threads: Each Puma worker has a thread pool to handle multiple requests concurrently.
    • Configured via: threads min_threads, max_threads
  • Workers: Separate processes forked from the master process.
    • Configured via: workers count
    • Each worker has its own thread pool.

# Load Balancing and Socket Accept Queue

  • The master process creates a shared listening socket.
  • All workers inherit this socket and compete to accept connections.
  • The OS manages a socket accept queue for incoming TCP connections.
  • When a connection is ready, the OS “wakes” one of the sleeping workers to handle it.

# Sleep and Wake Behavior

  • When a worker thread is ready to accept a request, it blocks (sleeps) until a connection is available.
  • The OS “wakes” up one thread or process to handle the connection.

# Low level error handler

See also https://github.com/puma/puma/blob/master/README.md#error-handling

In config/puma.rb

lowlevel_error_handler do |e, env, status|
  # Do stuff like report the error to your favorite error tracking service
  # the `env` object could have useful data to include in the reporting:
  #   env['REQUEST_URI']
  #   env['PATH_INFO']
  #   env['REQUEST_METHOD']
  #   env['REMOTE_ADDR']
  [500, {}, ["An error has occurred. Try again."]]
end

# Test it

Maybe try to send a malformed HTTP request using nc or openssl (if running on 443) but probably the easiest way is to inject some middleware in config.ru that just raises an error:

class LowleveErrorTest
  def initialize(app)
    @app = app
  end
  def call(env)
    raise "Simulated crash before app"
  end
end

use LowlevelErrorTest

run Rails.application
Rails.application.load_server

Search Results