---
name: "Perlbal::Manual::Internals"
section: "3pm"
platform: "linux"
package: "libperlbal-perl"
version: "1.80-4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Perlbal::Manual::Internals"
---

# Perlbal::Manual::Internals(3pm)

Perlbal's architecture at a glance

## NAME

Perlbal::Manual::Internals - Perlbal's architecture at a glance

### VERSION

Perlbal 1.78.

### DESCRIPTION

Connections come in from wherever and get to the TCPListener. It uses Service objects to determine what kind of Client\* to spawn. The Client classes then handle crafting the response for the user.

```
                            {{ INTERNET }}
                                  |
                                  v
              [Service]<===>[TCPListener]
                          ___/    |    \___
                         v        v        v
             [ClientManage]  [ClientHTTP] [ClientProxy]
                                                ^
                                                |
                                                v
                                          [BackendHTTP]
```

Perlbal decides what backend to send a request to randomly (only presently supported method). If that service has idle backend connections available, configured by `"backend_persist"` and `"connect_ahead"`, it will reuse those connections and greatly reduce latency. See more detail in Perlbal::Manual::LoadBalancer.

Perlbal also specializes in "spoonfeeding" data to slow clients. This allows backends to continue serving requests while Perlbal transfers responses back as fast as the client can read.

### Classes

The following is a brief introduction/overview to the main Perlbal's classes:

*Perlbal::Socket*

Descends from Danga::Socket.

Adds on to the base class to provide some functionality specifically useful for creating HTTP sockets.

Fields

- headers\_string

  Headers as they're being read.

- req\_headers

  The final Perlbal::HTTPHeaders object inbound.

- res\_headers

  Response headers outbound (Perlbal::HTTPHeaders object).

- create\_time

  Creation time.

- alive\_time

  Last time noted alive.

- state

  General purpose state; used by descendants.

- do\_die

  If on, die and do no further requests.

- read\_buf

  Arrayref of scalarref read from client.

- read\_ahead

  Bytes sitting in read\_buf.

- read\_size

  Total bytes read from client, ever.

- ditch\_leading\_rn

  If true, the next header parsing will ignore a leading \\r\\n.

- observed\_ip\_string

  If defined, contains the observed IP string of the peer we're serving. This is intended for holding the value of the X-Forwarded-For and using it to govern ACLs.

*Perlbal::TCPListener*

Descends from Perlbal::Socket.

Very lightweight and fast connection accept class. Takes incoming connections as fast as possible and passes them off, instantiating one of the various Client\* classes to handle it.

Fields

- service

  Perlbal::Service.

- hostport

  Scalar IP port of where this service is listening for new connections.

- sslopts

  The SSL Options.

  ```
      use Data::Dumper;
      warn Dumper( $tcp_listener->{'sslopts'} );
  ```

  The above lines would print something like the following:

  ```
      $VAR1 = {
                'ssl' => {
                           'SSL_cipher_list' => '...',
                           'SSL_cert_file' => '...',
                           'SSL_key_file' => ',,,',
                           'SSL_ca_path' => '...',
                           'SSL_verify_mode' => '...'
                         }
              };
  ```

- v6

  Boolean value stating whether the installation of Perlbal supports IPv6 (which basically boils down to Danga::Socket v1.6.1 and IO::Socket::INET6 being available).

*Perlbal::BackendHTTP*

Descends from Perlbal::Socket.

This class handles connections to the backend web nodes for getting data back to the user. This class is used by other classes such as Perlbal::ClientProxy to send a request to an internal node.

Fields

- client

  Perlbal::ClientProxy connection, or undef.

- service

  Perlbal::Service.

- pool

  Perlbal::Pool; whatever pool we spawned from.

- ip

  IP scalar.

- port

  Port scalar.

- ipport

  `"$ip:$port"`.

- reportto

  Object; must implement reporter interface.

- has\_attention

  Has been accepted by a webserver and we know for sure we're not just talking to the TCP stack.

- waiting\_options

  If true, we're waiting for an OPTIONS \* response to determine when we have attention.

- disconnect\_at

  Time this connection will be disconnected, if it's kept-alive and backend told us; otherwise `"undef"` for unknown.

- content\_length

  Length of document being transferred. Only applies when the backend server sends a content-length header.

- content\_length\_remain

  Bytes remaining to be read. Only applies when the backend server sends a content-length header.

- use\_count

  Number of requests this backend's been used for.

- generation

  Int; counts what generation we were spawned in.

- buffered\_upload\_mode

  Boolean. If on, we're doing a buffered upload transmit.

- scratch

  Extra storage; plugins can use it if they want.

*Perlbal::HTTPHeaders*

Header management. Parses headers (request and response) and stores data for further user. Also manages validation of the request line so that it conforms to HTTP specifications.

Fields

- headers

  href; lowercase header -\> comma-sep list of values.

- origcase

  Href; lowercase header -\> provided case.

- hdorder

  Aref; order headers were received (canonical order).

- method

  Scalar; request method (if GET request).

- uri

  Scalar; request URI (if GET request).

- type

  `"res"` or `"req"`.

- code

  HTTP response status code.

- codetext

  Status text that for response code.

- ver

  Version (string) "1.1".

- vernum

  Version (number: major\*1000+minor): "1.1" =\> 1001.

- responseLine

  First line of HTTP response (if response).

- requestLine

  First line of HTTP request (if request).

*Perlbal::ClientHTTPBase*

Descends from Perlbal::Socket.

Provides base functionality to Perlbal::ClientHTTP and Perlbal::ClientProxy. Notably, the ability to efficiently send files to the remote user. Also handles most of the state logic for statistics and such. Is also used for services of type `"selector"`. Perlbal::ClientHTTPBase then reads in the request headers, and asks the service to re-bless the client instance to a more specific type, for either a Perlbal::ClientProxy or Perlbal::ClientHTTP (depending on selector's mapping).

Fields

- service

  Perlbal::Service object.

- replacement\_uri

  URI to send instead of the one requested; this is used to instruct `"_serve_request"` to send an index file instead of trying to serve a directory and failing.

- scratch

  Extra storage; plugins can use it if they want.

- reproxy\_file

  Filename the backend told us to start opening.

- reproxy\_file\_size

  Size of file, once we `"stat()"` it.

- reproxy\_fh

  If needed, IO::Handle of fd.

- reproxy\_file\_offset

  How much we've sent from the file.

- post\_sendfile\_cb

  Subref to run after we're done sendfile'ing the current file.

- requests

  Number of requests this object has performed for the user.

- selector\_svc

  The original service from which we came.

- is\_ssl

  Whether the socket was SSL attached (restricted operations).

*Perlbal::ClientHTTP*

Descends from Perlbal::ClientHTTPBase.

Very simple and lightweight class. Handles sending files to the user without much overhead. Most of the functionality is contained in the parent class, and this class doesn't implement much new stuff.

Fields

- put\_in\_progress

  1 when we're currently waiting for an async job to return.

- put\_fh

  File handle to use for writing data.

- put\_fh\_filename

  Filename of put\_fh.

- put\_pos

  File offset to write next data at.

- content\_length

  Length of document being transferred.

- content\_length\_remain

  Bytes remaining to be read.

- chunked\_upload\_state

  Boolean/obj: if processing a chunked upload, Perlbal::ChunkedUploadState object, else undef.

*Perlbal::ClientProxy*

Descends from Perlbal::ClientHTTPBase.

Takes an incoming connection from a user and connects to a backend node (`"Perlbal::BackendHTTP"`) and relays the request. The backend can then either tell the proxy to reproxy and load a file from disk, or return a file directly, or just return a status message.

Fields

- backend

  Perlbal::BackendHTTP object (or `"undef"` if disconnected).

- backend\_requested

  True if we've requested a backend for this request.

- reconnect\_count

  Number of times we've tried to reconnect to backend.

- high\_priority

  Boolean; 1 if we are or were in the high priority queue.

- low\_priority

  Boolean; 1 if we are or were in the low priority queue.

- reproxy\_uris

  Arrayref; URIs to reproxy to, in order.

- reproxy\_expected\_size

  Int: size of response we expect to get back for reproxy.

- currently\_reproxying

  Arrayref; the host info and URI we're reproxying right now.

- content\_length\_remain

  Int: amount of data we're still waiting for.

- responded

  Bool: whether we've already sent a response to the user or not.

- last\_request\_time

  Int: time that we last received a request.

- primary\_res\_hdrs

  If defined, we are doing a transparent reproxy-URI and the headers we get back aren't necessarily the ones we want. Instead, get most headers from the provided `"res"` headers object here.

- is\_buffering

  Bool; if we're buffering some/all of a request to memory/disk.

- is\_writing

  Bool; if on, we currently have an `"aio_write"` out.

- start\_time

  Hi-res time when we started getting data to upload.

- bufh

  Buffered upload filehandle object.

- bufilename

  String; buffered upload filename.

- bureason

  String; if defined, the reason we're buffering to disk.

- buoutpos

  Int; buffered output position.

- backend\_stalled

  Boolean: if backend has shut off its reads because we're too slow.

- unread\_data\_waiting

  Boolean: if we shut off reads while we know data is yet to be read from client.

- chunked\_upload\_state

  Bool/obj: if processing a chunked upload, Perlbal::ChunkedUploadState object, else undef.

- request\_body\_length

  Integer: request's body length, either as-declared, or calculated after chunked upload is complete.

- last\_upload\_packet

  Unixtime we last sent a UDP upload packet. For perlbal sending out UDP packets related to upload status (for xmlhttprequest upload bar).

- upload\_session

  Client's self-generated upload session. For perlbal sending out UDP packets related to upload status (for xmlhttprequest upload bar).

- retry\_count

  Number of times we've retried this request so far after getting `500` errors.

*Perlbal::ClientManage*

Descends from Perlbal::Socket.

Simple interface that provides a way for users to use the management interface of Perlbal. You can connect to the management port (as defined in the config file) with a web browser or regular telnet (see Perlbal::Manual::Management for more information on this).

Fields

- service

  Perlbal::Service.

- buf

  Read buffer.

- is\_http

  Boolean stating whether the request is HTTP.

- ctx

  Perlbal::CommandContext.

*Perlbal::Service*

A service is a particular item that Perlbal is doing. Services can have a role which defines how they behave. Each service can also have a bunch of parameters set to further adjust its behavior. By itself, the Service class handles maintaining pools of backend connections and managing statistics about itself.

Fields

- name

  Name of the service.

- role

  Role type (`"web_server"`, `"reverse_proxy"`, etc).

- enabled

  Boolean; whether we're enabled or not (enabled = listening).

- pool

  Perlbal::Pool that we're using to allocate nodes if we're in proxy mode.

- listener

  Perlbal::TCPListener object, when enabled.

- reproxy\_cache

  Perlbal::Cache object, when enabled.

End-user tunables

- listen

  `"IP:port"` of where we're listening for new connections.

- docroot

  Document root for `"web_server"` role.

- dirindexing

  Boolean; directory indexing (for `"web_server"` role). Not async.

- index\_files

  Arrayref of filenames to try for index files.

- enable\_concatenate\_get

  Boolean; if user can request concatenated files.

- enable\_put

  Boolean; whether PUT is supported.

- max\_put\_size

  Max size in bytes of a put file.

- max\_chunked\_request\_size

  Max size in bytes of a chunked request (to be written to disk first).

- min\_put\_directory

  Number of directories required to exist at beginning of URIs in put.

- enable\_delete

  Boolean; whether DELETE is supported.

- high\_priority\_cookie

  Cookie name to check if the client's requests should be considered high priority.

  See also `"high_priority_cookie_contents"`.

- high\_priority\_cookie\_contents

  Aforementioned cookie value must contain this substring.

- backend\_persist\_cache

  Max number of persistent backends to hold onto while no clients.

- persist\_client

  Boolean; persistent connections for clients.

- persist\_backend

  Boolean; persistent connections for backends.

- verify\_backend

  Boolean; get attention of backend before giving it clients (using OPTIONS).

- verify\_backend\_path

  Path to check with the OPTIONS request (default is `"*"`).

- max\_backend\_uses

  Max requests to send per kept-alive backend (default 0 = unlimited).

- connect\_ahead

  Number of spare backends to connect to in advance all the time.

- buffer\_size

  How much data a Perlbal::ClientProxy object should buffer from a backend.

- buffer\_size\_reproxy\_url

  Same as above but for backends that are reproxying for us.

- queue\_relief\_size

  Number of outstanding standard priority connections to activate pressure relief at.

- queue\_relief\_chance

  Int, 0-100; % chance to take a standard priority request when we're in pressure relief mode.

- trusted\_upstream\_proxies

  Array of Net::Netmask objects containing netmasks for trusted upstreams.

- always\_trusted

  Boolean; if true, always trust upstreams.

- blind\_proxy

  Boolean; if true, do not modify `"X-Forwarded-For"`, `"X-Host"`, or `"X-Forwarded-Host"` headers.

- enable\_reproxy

  Boolean; if true, advertise that server will reproxy files and/or URLs.

- reproxy\_cache\_maxsize

  Maximum number of reproxy results to be cached. (0 is disabled and default).

- client\_sndbuf\_size

  Bytes for `"SO_SNDBUF"`.

- server\_process

  Path to server process (executable).

- persist\_client\_idle\_timeout

  Keep-alive timeout in seconds for clients (default is 30).

- idle\_timeout

  Idle timeout outside of keep-alive time (default is 30).

Internal state

- waiting\_clients

  Arrayref of clients waiting for backendhttp connections.

- waiting\_clients\_highpri

  Arrayref of high-priority clients waiting for backendhttp connections.

- waiting\_clients\_lowpri

  Arrayref of low-priority clients waiting for backendhttp connections.

- waiting\_client\_count

  Number of clients waiting for backends.

- waiting\_client\_map

  Map of clientproxy fd -\> 1 (if they're waiting for a connection).

- pending\_connects

  Hashref of `"ip:port"` -\> `$time` (only one pending connect to backend at a time).

- pending\_connect\_count

  Number of outstanding backend connects.

- bored\_backends

  Arrayref of backends we've already connected to, but haven't got clients.

- hooks

  Hashref: hookname =\> \[ \[ plugin, ref \], \[ plugin, ref \], ... \].

- plugins

  Hashref: name =\> 1.

- plugin\_order

  Arrayref: name, name, name...

- plugin\_setters

  Hashref: { plugin\_name =\> { key\_name =\> coderef } }.

- extra\_config

  Hashref with extra config options; name =\> values.

- spawn\_lock

  Boolean; if true, we're currently in `"spawn_backends"`.

- extra\_headers

  { insert =\> \[ \[ header, value \], ... \], remove =\> \[ header, header, ... \], set =\> \[ \[ header, value \], ... \] }.

  Used in header management interface.

- generation

  Int; generation count so we can slough off backends from old pools.

- backend\_no\_spawn

  { "ip:port" =\> 1 }.

  If on, `"spawn_backends"` will ignore this `"ip:port"` combo.

- buffer\_backend\_connect

  0 if off; otherwise, number of bytes to buffer before we ask for a backend.

- selector

  CODE ref, or undef, for role `"selector"` services.

- default\_service

  Name of a service a selector should default to.

- buffer\_uploads

  Boolean; enable/disable the buffered uploads to disk system.

- buffer\_uploads\_path

  Path to store buffered upload files.

- buffer\_upload\_threshold\_time

  Int; buffer uploads estimated to take longer than this.

- buffer\_upload\_threshold\_size

  Int; buffer uploads greater than this size (in bytes).

- buffer\_upload\_threshold\_rate

  Int; buffer uploads uploading at less than this rate (in bytes/sec).

- upload\_status\_listeners

  Comma separated list of `"ip:port"` of UDP upload status receivers.

- upload\_status\_listeners\_sockaddr

  Arrayref of sockaddrs (packed ip/port).

- enable\_ssl

  Boolean; whether this service speaks SSL to the client.

- ssl\_key\_file

  File path to key pem file.

- ssl\_cert\_file

  File to path to cert pem file.

- ssl\_cipher\_list

  OpenSSL cipher list string.

- ssl\_ca\_path

  Path to certificates directory.

- ssl\_verify\_mode

  Int; verification mode, see IO::Socket::SSL.

- enable\_error\_retries

  Boolean; whether we should retry requests after errors.

- error\_retry\_schedule

  Comma-separated seconds (full or partial) to delay between retries.

- latency

  Milliseconds of latency to add to request.

- server\_tokens

  Boolean; whether to provide a "Server" header.

- \_stat\_requests

  Total requests to this service.

- \_stat\_cache\_hits

  Total requests to this service that were served via the reproxy-url cache.
