Module: Hyperion

Defined in:
lib/hyperion.rb,
lib/hyperion/cli.rb,
lib/hyperion/tls.rb,
lib/hyperion/pool.rb,
lib/hyperion/config.rb,
lib/hyperion/logger.rb,
lib/hyperion/master.rb,
lib/hyperion/parser.rb,
lib/hyperion/server.rb,
lib/hyperion/worker.rb,
lib/hyperion/metrics.rb,
lib/hyperion/request.rb,
lib/hyperion/version.rb,
lib/hyperion/connection.rb,
lib/hyperion/fiber_local.rb,
lib/hyperion/thread_pool.rb,
lib/hyperion/adapter/rack.rb,
lib/hyperion/http2_handler.rb,
lib/hyperion/worker_health.rb,
lib/hyperion/response_writer.rb,
lib/hyperion/admin_middleware.rb,
lib/hyperion/prometheus_exporter.rb

Defined Under Namespace

Modules: Adapter, FiberLocal, PrometheusExporter, TLS, WorkerHealth Classes: AdminMiddleware, CLI, CParser, Config, Connection, Error, Http2Handler, Logger, Master, Metrics, ParseError, Parser, Pool, Request, ResponseWriter, Server, ThreadPool, UnsupportedError, Worker

Constant Summary collapse

VERSION =
'1.4.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.log_requests=(value) ⇒ Object (writeonly)

Sets the attribute log_requests

Parameters:

  • value

    the value to set the attribute log_requests to.



18
19
20
# File 'lib/hyperion.rb', line 18

def log_requests=(value)
  @log_requests = value
end

.loggerObject



14
15
16
# File 'lib/hyperion.rb', line 14

def logger
  @logger ||= Logger.new
end

Class Method Details

.c_parser_available?Boolean

Whether the llhttp C extension loaded. False on JRuby/TruffleRuby and any environment where extconf.rb / make failed at install time. The pure-Ruby parser handles those cases correctly but is ~2× slower on parse-heavy workloads. Operators running production should confirm this returns true; CLI emits a startup banner if it doesn’t.

Returns:

  • (Boolean)


41
42
43
# File 'lib/hyperion.rb', line 41

def c_parser_available?
  defined?(::Hyperion::CParser) && ::Hyperion::CParser.respond_to?(:build_response_head)
end

.log_requests?Boolean

Per-request access logging is ON by default — matches Puma/Rails operator expectations (Rails::Rack::Logger emits one line per request out of the box). Operators can disable it via ‘–no-log-requests`, `HYPERION_LOG_REQUESTS=0|false|no|off`, or programmatically via `Hyperion.log_requests = false`. When false, Connection skips ALL access-log work — no Process.clock_gettime, no hash build, nothing.

The hot path uses Logger#access (single-interpolation line build, per-thread cached timestamp, lock-free emit) so default-ON throughput stays well above Puma’s default-OFF baseline.

Returns:

  • (Boolean)


55
56
57
58
59
60
61
62
63
64
65
# File 'lib/hyperion.rb', line 55

def log_requests?
  return @log_requests unless @log_requests.nil?

  env = ENV['HYPERION_LOG_REQUESTS']&.downcase
  @log_requests =
    case env
    when '0', 'false', 'no', 'off' then false
    when '1', 'true', 'yes', 'on'  then true
    else true # default ON
    end
end

.metricsObject



20
21
22
# File 'lib/hyperion.rb', line 20

def metrics
  @metrics ||= Metrics.new
end

.statsObject



24
25
26
# File 'lib/hyperion.rb', line 24

def stats
  metrics.snapshot
end

.warmup!Object

Pre-fork warmup. Run by Master and CLI single-mode BEFORE children are forked (or before the lone worker starts accepting). Pre-allocates the Rack adapter’s object pools and eager-touches lazily-resolved constants so each forked child inherits warm memory via copy-on-write — the first N requests on a fresh worker no longer pay the allocation / autoload tax that would otherwise serialize behind the GVL on cold start.

Idempotent — second and later calls are no-ops. Failures are swallowed with a warn log: warmup is an optimization, not a correctness gate. If, for instance, OpenSSL can’t be required in some odd environment, we’d rather start cold than refuse to boot.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hyperion.rb', line 78

def warmup!
  return if @warmed

  @warmed = true

  if defined?(::Hyperion::Adapter::Rack) && ::Hyperion::Adapter::Rack.respond_to?(:warmup_pool)
    ::Hyperion::Adapter::Rack.warmup_pool(8)
  end

  # Touch the C extension's response-head builder so its lazily-initialized
  # internal state runs in the master, not in every child after fork.
  ::Hyperion::CParser.respond_to?(:build_response_head) if defined?(::Hyperion::CParser)

  # Eager-load TLS / SSLSocket. The sendfile path's `is_a?` check would
  # otherwise trigger autoload in the worker on the first TLS response.
  require 'openssl'
  defined?(::OpenSSL::SSL::SSLSocket) && ::OpenSSL::SSL::SSLSocket.name

  # Force Ruby's tzinfo / strftime-cache load by emitting one httpdate.
  # Subsequent calls hit the per-thread `cached_date` slot in response_writer.
  Time.now.httpdate
  nil
rescue StandardError => e
  Hyperion.logger.warn { { message: 'warmup failed (non-fatal)', error: e.message } }
  nil
end

.yjit_enabled?Boolean

Whether YJIT is currently enabled in this Ruby process. False on Rubies that don’t ship YJIT (JRuby, TruffleRuby) and on CRuby builds compiled without YJIT support. Cheap (no allocations) — safe to call from hot paths if needed for diagnostics.

Returns:

  • (Boolean)


32
33
34
# File 'lib/hyperion.rb', line 32

def yjit_enabled?
  defined?(::RubyVM::YJIT) && ::RubyVM::YJIT.enabled?
end