{
  "type": "module",
  "source": "doc/api/api-api-lifecycle.md",
  "modules": [
    {
      "textRaw": "Client Lifecycle",
      "name": "client_lifecycle",
      "type": "module",
      "desc": "<p>An Undici <a href=\"/docs/docs/api/Client.html\">Client</a> can be best described as a state machine. The following list is a summary of the various state transitions the <code>Client</code> will go through in its lifecycle. This document also contains detailed breakdowns of each state.</p>\n<blockquote>\n<p>This diagram is not a perfect representation of the undici Client. Since the Client class is not actually implemented as a state-machine, actual execution may deviate slightly from what is described below. Consider this as a general resource for understanding the inner workings of the Undici client rather than some kind of formal specification.</p>\n</blockquote>",
      "modules": [
        {
          "textRaw": "State Transition Overview",
          "name": "state_transition_overview",
          "type": "module",
          "desc": "<ul>\n<li>A <code>Client</code> begins in the <strong>idle</strong> state with no socket connection and no requests in queue.\n<ul>\n<li>The <em>connect</em> event transitions the <code>Client</code> to the <strong>pending</strong> state where requests can be queued prior to processing.</li>\n<li>The <em>close</em> and <em>destroy</em> events transition the <code>Client</code> to the <strong>destroyed</strong> state. Since there are no requests in the queue, the <em>close</em> event immediately transitions to the <strong>destroyed</strong> state.</li>\n</ul>\n</li>\n<li>The <strong>pending</strong> state indicates the underlying socket connection has been successfully established and requests are queueing.\n<ul>\n<li>The <em>process</em> event transitions the <code>Client</code> to the <strong>processing</strong> state where requests are processed.</li>\n<li>If requests are queued, the <em>close</em> event transitions to the <strong>processing</strong> state; otherwise, it transitions to the <strong>destroyed</strong> state.</li>\n<li>The <em>destroy</em> event transitions to the <strong>destroyed</strong> state.</li>\n</ul>\n</li>\n<li>The <strong>processing</strong> state initializes to the <strong>processing.running</strong> state.\n<ul>\n<li>If the current request requires draining, the <em>needDrain</em> event transitions the <code>Client</code> into the <strong>processing.busy</strong> state which will return to the <strong>processing.running</strong> state with the <em>drainComplete</em> event.</li>\n<li>After all queued requests are completed, the <em>keepalive</em> event transitions the <code>Client</code> back to the <strong>pending</strong> state. If no requests are queued during the timeout, the <strong>close</strong> event transitions the <code>Client</code> to the <strong>destroyed</strong> state.</li>\n<li>If the <em>close</em> event is fired while the <code>Client</code> still has queued requests, the <code>Client</code> transitions to the <strong>process.closing</strong> state where it will complete all existing requests before firing the <em>done</em> event.</li>\n<li>The <em>done</em> event gracefully transitions the <code>Client</code> to the <strong>destroyed</strong> state.</li>\n<li>At any point in time, the <em>destroy</em> event will transition the <code>Client</code> from the <strong>processing</strong> state to the <strong>destroyed</strong> state, destroying any queued requests.</li>\n</ul>\n</li>\n<li>The <strong>destroyed</strong> state is a final state and the <code>Client</code> is no longer functional.</li>\n</ul>\n<p>A state diagram representing an Undici Client instance:</p>\n<pre><code class=\"language-mermaid\">stateDiagram-v2\n  [*] --> idle\n  idle --> pending : connect\n  idle --> destroyed : destroy/close\n\n  pending --> idle : timeout\n  pending --> destroyed : destroy\n\n  state close_fork &#x3C;&#x3C;fork>>\n  pending --> close_fork : close\n  close_fork --> processing\n  close_fork --> destroyed\n\n  pending --> processing : process\n\n  processing --> pending : keepalive\n  processing --> destroyed : done\n  processing --> destroyed : destroy\n\n  destroyed --> [*]\n\n  state processing {\n      [*] --> running\n      running --> closing : close\n      running --> busy : needDrain\n      busy --> running : drainComplete\n      running --> [*] : keepalive\n      closing --> [*] : done\n  }\n</code></pre>",
          "displayName": "State Transition Overview"
        },
        {
          "textRaw": "State details",
          "name": "state_details",
          "type": "module",
          "modules": [
            {
              "textRaw": "idle",
              "name": "idle",
              "type": "module",
              "desc": "<p>The <strong>idle</strong> state is the initial state of a <code>Client</code> instance. While an <code>origin</code> is required for instantiating a <code>Client</code> instance, the underlying socket connection will not be established until a request is queued using <a href=\"/docs/docs/api/Client.html#clientdispatchoptions-handlers\"><code>Client.dispatch()</code></a>. By calling <code>Client.dispatch()</code> directly or using one of the multiple implementations (<a href=\"/docs/docs/api/Client.html#clientconnectoptions-callback\"><code>Client.connect()</code></a>, <a href=\"/docs/docs/api/Client.html#clientpipelineoptions-handler\"><code>Client.pipeline()</code></a>, <a href=\"/docs/docs/api/Client.html#clientrequestoptions-callback\"><code>Client.request()</code></a>, <a href=\"/docs/docs/api/Client.html#clientstreamoptions-factory-callback\"><code>Client.stream()</code></a>, and <a href=\"/docs/docs/api/Client.html#clientupgradeoptions-callback\"><code>Client.upgrade()</code></a>), the <code>Client</code> instance will transition from <strong>idle</strong> to <a href=\"/docs/docs/api/Client.html#pending\"><strong>pending</strong></a> and then most likely directly to <a href=\"/docs/docs/api/Client.html#processing\"><strong>processing</strong></a>.</p>\n<p>Calling <a href=\"/docs/docs/api/Client.html#clientclosecallback\"><code>Client.close()</code></a> or <a href=\"/docs/docs/api/Client.html#clientdestroyerror-callback\"><code>Client.destroy()</code></a> transitions directly to the <a href=\"/docs/docs/api/Client.html#destroyed\"><strong>destroyed</strong></a> state since the <code>Client</code> instance will have no queued requests in this state.</p>",
              "displayName": "idle"
            },
            {
              "textRaw": "pending",
              "name": "pending",
              "type": "module",
              "desc": "<p>The <strong>pending</strong> state signifies a non-processing <code>Client</code>. Upon entering this state, the <code>Client</code> establishes a socket connection and emits the <a href=\"/docs/docs/api/Client.html#event-connect\"><code>'connect'</code></a> event signalling a connection was successfully established with the <code>origin</code> provided during <code>Client</code> instantiation. The internal queue is initially empty, and requests can start queueing.</p>\n<p>Calling <a href=\"/docs/docs/api/Client.html#clientclosecallback\"><code>Client.close()</code></a> with queued requests, transitions the <code>Client</code> to the <a href=\"/docs/docs/api/Client.html#processing\"><strong>processing</strong></a> state. Without queued requests, it transitions to the <a href=\"/docs/docs/api/Client.html#destroyed\"><strong>destroyed</strong></a> state.</p>\n<p>Calling <a href=\"/docs/docs/api/Client.html#clientdestroyerror-callback\"><code>Client.destroy()</code></a> transitions directly to the <a href=\"/docs/docs/api/Client.html#destroyed\"><strong>destroyed</strong></a> state regardless of existing requests.</p>",
              "displayName": "pending"
            },
            {
              "textRaw": "processing",
              "name": "processing",
              "type": "module",
              "desc": "<p>The <strong>processing</strong> state is a state machine within itself. It initializes to the <a href=\"/docs/docs/api/Client.html#running\"><strong>processing.running</strong></a> state. The <a href=\"/docs/docs/api/Client.html#clientdispatchoptions-handlers\"><code>Client.dispatch()</code></a>, <a href=\"/docs/docs/api/Client.html#clientclosecallback\"><code>Client.close()</code></a>, and <a href=\"/docs/docs/api/Client.html#clientdestroyerror-callback\"><code>Client.destroy()</code></a> can be called at any time while the <code>Client</code> is in this state. <code>Client.dispatch()</code> will add more requests to the queue while existing requests continue to be processed. <code>Client.close()</code> will transition to the <a href=\"/docs/docs/api/Client.html#closing\"><strong>processing.closing</strong></a> state. And <code>Client.destroy()</code> will transition to <a href=\"/docs/docs/api/Client.html#destroyed\"><strong>destroyed</strong></a>.</p>",
              "modules": [
                {
                  "textRaw": "running",
                  "name": "running",
                  "type": "module",
                  "desc": "<p>In the <strong>processing.running</strong> sub-state, queued requests are being processed in a FIFO order. If a request body requires draining, the <em>needDrain</em> event transitions to the <a href=\"/docs/docs/api/Client.html#busy\"><strong>processing.busy</strong></a> sub-state. The <em>close</em> event transitions the Client to the <a href=\"/docs/docs/api/Client.html#closing\"><strong>process.closing</strong></a> sub-state. If all queued requests are processed and neither <a href=\"/docs/docs/api/Client.html#clientclosecallback\"><code>Client.close()</code></a> nor <a href=\"/docs/docs/api/Client.html#clientdestroyerror-callback\"><code>Client.destroy()</code></a> are called, then the <a href=\"/docs/docs/api/Client.html#processing\"><strong>processing</strong></a> machine will trigger a <em>keepalive</em> event transitioning the <code>Client</code> back to the <a href=\"/docs/docs/api/Client.html#pending\"><strong>pending</strong></a> state. During this time, the <code>Client</code> is waiting for the socket connection to timeout, and once it does, it triggers the <em>timeout</em> event and transitions to the <a href=\"/docs/docs/api/Client.html#idle\"><strong>idle</strong></a> state.</p>",
                  "displayName": "running"
                },
                {
                  "textRaw": "busy",
                  "name": "busy",
                  "type": "module",
                  "desc": "<p>This sub-state is only entered when a request body is an instance of <a href=\"https://nodejs.org/api/stream.html\">Stream</a> and requires draining. The <code>Client</code> cannot process additional requests while in this state and must wait until the currently processing request body is completely drained before transitioning back to <a href=\"/docs/docs/api/Client.html#running\"><strong>processing.running</strong></a>.</p>",
                  "displayName": "busy"
                },
                {
                  "textRaw": "closing",
                  "name": "closing",
                  "type": "module",
                  "desc": "<p>This sub-state is only entered when a <code>Client</code> instance has queued requests and the <a href=\"/docs/docs/api/Client.html#clientclosecallback\"><code>Client.close()</code></a> method is called. In this state, the <code>Client</code> instance continues to process requests as usual, with the one exception that no additional requests can be queued. Once all of the queued requests are processed, the <code>Client</code> will trigger the <em>done</em> event gracefully entering the <a href=\"/docs/docs/api/Client.html#destroyed\"><strong>destroyed</strong></a> state without an error.</p>",
                  "displayName": "closing"
                }
              ],
              "displayName": "processing"
            },
            {
              "textRaw": "destroyed",
              "name": "destroyed",
              "type": "module",
              "desc": "<p>The <strong>destroyed</strong> state is a final state for the <code>Client</code> instance. Once in this state, a <code>Client</code> is nonfunctional. Calling any other <code>Client</code> methods will result in an <code>ClientDestroyedError</code>.</p>",
              "displayName": "destroyed"
            }
          ],
          "displayName": "State details"
        }
      ],
      "displayName": "Client Lifecycle"
    }
  ]
}