All Downloads are FREE. Search and download functionalities are using the official Maven repository.

okhttp3.EventListener.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0-alpha.14
Show newest version
/*
 * Copyright (C) 2017 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package okhttp3

import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Proxy

/**
 * Listener for metrics events. Extend this class to monitor the quantity, size, and duration of
 * your application's HTTP calls.
 *
 * All start/connect/acquire events will eventually receive a matching end/release event, either
 * successful (non-null parameters), or failed (non-null throwable).  The first common parameters of
 * each event pair are used to link the event in case of concurrent or repeated events e.g.
 * dnsStart(call, domainName) -> dnsEnd(call, domainName, inetAddressList).
 *
 * Nesting is as follows
 *
 *  * call -> (dns -> connect -> secure connect)* -> request events
 *  * call -> (connection acquire/release)*
 *
 * Request events are ordered:
 *
 * requestHeaders -> requestBody -> responseHeaders -> responseBody
 *
 * Since connections may be reused, the dns and connect events may not be present for a call, or may
 * be repeated in case of failure retries, even concurrently in case of happy eyeballs type
 * scenarios. A redirect cross domain, or to use https may cause additional connection and request
 * events.
 *
 * All event methods must execute fast, without external locking, cannot throw exceptions, attempt
 * to mutate the event parameters, or be re-entrant back into the client. Any IO - writing to files
 * or network should be done asynchronously.
 */
abstract class EventListener {
  /**
   * Invoked as soon as a call is enqueued or executed by a client. In case of thread or stream
   * limits, this call may be executed well before processing the request is able to begin.
   *
   * This will be invoked only once for a single [Call]. Retries of different routes or redirects
   * will be handled within the boundaries of a single [callStart] and [callEnd]/[callFailed] pair.
   */
  open fun callStart(
    call: Call
  ) {
  }

  /**
   * Invoked just prior to a DNS lookup. See [Dns.lookup].
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different host.
   *
   * If the [Call] is able to reuse an existing pooled connection, this method will not be invoked.
   * See [ConnectionPool].
   */
  open fun dnsStart(
    call: Call,
    domainName: String
  ) {
  }

  /**
   * Invoked immediately after a DNS lookup.
   *
   * This method is invoked after [dnsStart].
   */
  open fun dnsEnd(
    call: Call,
    domainName: String,
    inetAddressList: List<@JvmSuppressWildcards InetAddress>
  ) {
  }

  /**
   * Invoked just prior to initiating a socket connection.
   *
   * This method will be invoked if no existing connection in the [ConnectionPool] can be reused.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address, or a connection is retried.
   */
  open fun connectStart(
    call: Call,
    inetSocketAddress: InetSocketAddress,
    proxy: Proxy
  ) {
  }

  /**
   * Invoked just prior to initiating a TLS connection.
   *
   * This method is invoked if the following conditions are met:
   *
   *  * The [Call.request] requires TLS.
   *
   *  * No existing connection from the [ConnectionPool] can be reused.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address, or a connection is retried.
   */
  open fun secureConnectStart(
    call: Call
  ) {
  }

  /**
   * Invoked immediately after a TLS connection was attempted.
   *
   * This method is invoked after [secureConnectStart].
   */
  open fun secureConnectEnd(
    call: Call,
    handshake: Handshake?
  ) {
  }

  /**
   * Invoked immediately after a socket connection was attempted.
   *
   * If the `call` uses HTTPS, this will be invoked after [secureConnectEnd], otherwise it will
   * invoked after [connectStart].
   */
  open fun connectEnd(
    call: Call,
    inetSocketAddress: InetSocketAddress,
    proxy: Proxy,
    protocol: Protocol?
  ) {
  }

  /**
   * Invoked when a connection attempt fails. This failure is not terminal if further routes are
   * available and failure recovery is enabled.
   *
   * If the `call` uses HTTPS, this will be invoked after [secureConnectEnd], otherwise it will
   * invoked after [connectStart].
   */
  open fun connectFailed(
    call: Call,
    inetSocketAddress: InetSocketAddress,
    proxy: Proxy,
    protocol: Protocol?,
    ioe: IOException
  ) {
  }

  /**
   * Invoked after a connection has been acquired for the `call`.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response
   * to the [Call.request] is a redirect to a different address.
   */
  open fun connectionAcquired(
    call: Call,
    connection: Connection
  ) {
  }

  /**
   * Invoked after a connection has been released for the `call`.
   *
   * This method is always invoked after [connectionAcquired].
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address.
   */
  open fun connectionReleased(
    call: Call,
    connection: Connection
  ) {
  }

  /**
   * Invoked just prior to sending request headers.
   *
   * The connection is implicit, and will generally relate to the last [connectionAcquired] event.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address.
   */
  open fun requestHeadersStart(
    call: Call
  ) {
  }

  /**
   * Invoked immediately after sending request headers.
   *
   * This method is always invoked after [requestHeadersStart].
   *
   * @param request the request sent over the network. It is an error to access the body of this
   *     request.
   */
  open fun requestHeadersEnd(call: Call, request: Request) {
  }

  /**
   * Invoked just prior to sending a request body.  Will only be invoked for request allowing and
   * having a request body to send.
   *
   * The connection is implicit, and will generally relate to the last [connectionAcquired] event.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address.
   */
  open fun requestBodyStart(
    call: Call
  ) {
  }

  /**
   * Invoked immediately after sending a request body.
   *
   * This method is always invoked after [requestBodyStart].
   */
  open fun requestBodyEnd(
    call: Call,
    byteCount: Long
  ) {
  }

  /**
   * Invoked when a request fails to be written.
   *
   * This method is invoked after [requestHeadersStart] or [requestBodyStart]. Note that request
   * failures do not necessarily fail the entire call.
   */
  open fun requestFailed(
    call: Call,
    ioe: IOException
  ) {
  }

  /**
   * Invoked just prior to receiving response headers.
   *
   * The connection is implicit, and will generally relate to the last [connectionAcquired] event.
   *
   * This can be invoked more than 1 time for a single [Call]. For example, if the response to the
   * [Call.request] is a redirect to a different address.
   */
  open fun responseHeadersStart(
    call: Call
  ) {
  }

  /**
   * Invoked immediately after receiving response headers.
   *
   * This method is always invoked after [responseHeadersStart].
   *
   * @param response the response received over the network. It is an error to access the body of
   *     this response.
   */
  open fun responseHeadersEnd(
    call: Call,
    response: Response
  ) {
  }

  /**
   * Invoked just prior to receiving the response body.
   *
   * The connection is implicit, and will generally relate to the last [connectionAcquired] event.
   *
   * This will usually be invoked only 1 time for a single [Call], exceptions are a limited set of
   * cases including failure recovery.
   */
  open fun responseBodyStart(
    call: Call
  ) {
  }

  /**
   * Invoked immediately after receiving a response body and completing reading it.
   *
   * Will only be invoked for requests having a response body e.g. won't be invoked for a web socket
   * upgrade.
   *
   * This method is always invoked after [requestBodyStart].
   */
  open fun responseBodyEnd(
    call: Call,
    byteCount: Long
  ) {
  }

  /**
   * Invoked when a response fails to be read.
   *
   * This method is invoked after [responseHeadersStart] or [responseBodyStart]. Note that response
   * failures do not necessarily fail the entire call.
   */
  open fun responseFailed(
    call: Call,
    ioe: IOException
  ) {
  }

  /**
   * Invoked immediately after a call has completely ended.  This includes delayed consumption
   * of response body by the caller.
   *
   * This method is always invoked after [callStart].
   */
  open fun callEnd(
    call: Call
  ) {
  }

  /**
   * Invoked when a call fails permanently.
   *
   * This method is always invoked after [callStart].
   */
  open fun callFailed(
    call: Call,
    ioe: IOException
  ) {
  }

  interface Factory {
    /**
     * Creates an instance of the [EventListener] for a particular [Call]. The returned
     * [EventListener] instance will be used during the lifecycle of the `call`.
     *
     * This method is invoked after the `call` is created. See [OkHttpClient.newCall].
     *
     * **It is an error for implementations to issue any mutating operations on the `call` instance
     * from this method.**
     */
    fun create(call: Call): EventListener

    companion object {
      // This lambda conversion is for Kotlin callers expecting a Java SAM (single-abstract-method).
      @JvmName("-deprecated_Factory")
      inline operator fun invoke(
        crossinline block: (call: Call) -> EventListener
      ): Factory = object : Factory {
        override fun create(call: Call) = block(call)
      }
    }
  }

  companion object {
    @JvmField
    val NONE: EventListener = object : EventListener() {
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy