Packages

class MethodBuilder extends MethodBuilderScaladoc[MethodBuilder]

MethodBuilder is a collection of APIs for client configuration at a higher level than the Finagle 6 APIs while improving upon the deprecated ClientBuilder. MethodBuilder provides:

  • Logical success rate metrics.
  • Retries based on application-level requests and responses (e.g. an HTTP 503 response code).
  • Configuration of per-attempt and total timeouts.

All of these can be customized per method (or endpoint) while sharing a single underlying Finagle client. Concretely, a single service might offer both GET statuses/show/:id as well as POST statuses/update, whilst each having wildly different characteristics. The GET is idempotent and has a tight latency distribution while the POST is not idempotent and has a wide latency distribution. If users want different configurations, without MethodBuilder they must create separate Finagle clients for each grouping. While long-lived clients in Finagle are not expensive, they are not free. They create duplicate metrics and waste heap, file descriptors, and CPU.

Example

A client that has timeouts and retries on a 418 status code.

import com.twitter.conversions.time._
import com.twitter.finagle.Http
import com.twitter.finagle.service.{ReqRep, ResponseClass}
import com.twitter.util.Return

val client: Http.Client = ???
client.methodBuilder("inet!example.com:80")
  .withTimeoutPerRequest(50.milliseconds)
  .withTimeoutTotal(100.milliseconds)
  .withRetryForClassifier {
    case ReqRep(_, Return(rep)) if rep.statusCode == 418 => ResponseClass.RetryableFailure
  }
  .newService("an_endpoint_name")

Timeouts

Defaults to using the StackClient's configuration.

An example of setting a per-request timeout of 50 milliseconds and a total timeout of 100 milliseconds:

import com.twitter.conversions.time._
import com.twitter.finagle.Http
import com.twitter.finagle.http.MethodBuilder

val builder: MethodBuilder = ???
builder
  .withTimeoutPerRequest(50.milliseconds)
  .withTimeoutTotal(100.milliseconds)

Retries

Retries are intended to help clients improve success rate by trying failed requests additional times. Care must be taken by developers to only retry when it is known to be safe to issue the request multiple times. This is because the client cannot always be sure what the backend service has done. An example of a request that is safe to retry would be a read-only request.

Defaults to using the client's ResponseClassifier to retry failures marked as retryable. See withRetryForClassifier for details.

A com.twitter.finagle.service.RetryBudget is used to prevent retries from overwhelming the backend service. The budget is shared across clients created from an initial MethodBuilder. As such, even if the retry rules deem the request retryable, it may not be retried if there is insufficient budget.

Finagle will automatically retry failures that are known to be safe to retry via com.twitter.finagle.service.RequeueFilter. This includes WriteExceptions and retryable nacks. As these should have already been retried, we avoid retrying them again by ignoring them at this layer.

Additional information regarding retries can be found in the user guide.

The classifier is also used to determine the logical success metrics of the method. Logical here means after any retries are run. For example should a request result in retryable failure on the first attempt, but succeed upon retry, this is exposed through metrics as a success. Logical success rate metrics are scoped to "clnt/your_client_label/method_name/logical" and get "success" and "requests" counters along with a "request_latency_ms" stat.

Unsuccessful requests are logged at com.twitter.logging.Level.DEBUG level. Further details, including the request and response, are available at TRACE level.

See also

The user guide.

com.twitter.finagle.Http.Client.methodBuilder to construct instances.

Linear Supertypes
MethodBuilderScaladoc[MethodBuilder], AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. MethodBuilder
  2. MethodBuilderScaladoc
  3. AnyRef
  4. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  6. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  7. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  8. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  9. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  10. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  11. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  12. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  13. def newService(methodName: String): Service[Request, Response]

    Construct a Service to be used for the methodName method.

    Construct a Service to be used for the methodName method.

    methodName

    used for scoping metrics (e.g. "clnt/your_client_label/method_name").

  14. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  15. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  16. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  17. def toString(): String
    Definition Classes
    AnyRef → Any
  18. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  19. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  20. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  21. def withRetryDisabled: MethodBuilder

    Disables "application" level retries.

    Disables "application" level retries.

    This does not disable retries of failures that are known to be safe to retry via com.twitter.finagle.service.RequeueFilter.

    This causes the logical success metrics to be based on the default response classifier rules of a Return response is a success, while everything else is not.

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. import com.twitter.finagle.http.Http
      
      val client: Http.Client = ???
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withRetryDisabled
    See also

    withRetryForClassifier

  22. def withRetryForClassifier(classifier: ResponseClassifier): MethodBuilder

    Retry based on ResponseClassifier.

    Retry based on ResponseClassifier.

    The default behavior is to use the client's classifier which is typically configured through theClient.withResponseClassifier or ClientBuilder.withResponseClassifier.

    This classifier is used to determine which requests are unsuccessful. This is the basis for measuring the logical success metrics as well as logging unsuccessful requests at debug level.

    classifier

    when a Failed with retryable is true is returned for a given ReqRep, the request will be retried. This is often a ResponseClass.RetryableFailure.

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. For example, retrying on a 418 status code:

      import com.twitter.conversions.time._
      import com.twitter.finagle.http.Http
      import com.twitter.finagle.service.{ReqRep, ResponseClass}
      import com.twitter.util.Return
      
      val client: Http.Client = ???
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withRetryForClassifier {
        case ReqRep(_, Return(rep)) if rep.statusCode == 418 => ResponseClass.RetryableFailure
      }

      The classifier is also used to determine the logical success metrics of the client.

    See also

    response classification user guide

    withRetryDisabled

  23. def withTimeoutPerRequest(howLong: Tunable[Duration]): MethodBuilder

    How long a single request is given to complete.

    How long a single request is given to complete.

    If there are retries, each attempt is given up to this amount of time.

    If a request does not complete within this time, the response will be satisfied with a com.twitter.finagle.IndividualRequestTimeoutException.

    Defaults to using the client's configuration for com.twitter.finagle.service.TimeoutFilter.Param(timeout), which is typically set via com.twitter.finagle.param.CommonParams.withRequestTimeout.

    howLong

    how long, from the initial request issuance, an individual attempt given to complete. If it is not finite (e.g. Duration.Top), no method specific timeout will be applied.

    returns

    a new instance with all other settings copied

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. For example, a per-request timeout of 50 milliseconds:

      import com.twitter.conversions.time._
      import com.twitter.finagle.http.Http
      import com.twitter.util.Duration
      import com.twitter.util.tunable.Tunable
      
      val client: Http.Client = ???
      val tunableTimeout: Tunable[Duration] = Tunable.const("id", 50.milliseconds)
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withTimeoutPerRequest(tunableTimeout))
    See also

    withTimeoutTotal(Tunable[Duration])

  24. def withTimeoutPerRequest(howLong: Duration): MethodBuilder

    How long a single request is given to complete.

    How long a single request is given to complete.

    If there are retries, each attempt is given up to this amount of time.

    If a request does not complete within this time, the response will be satisfied with a com.twitter.finagle.IndividualRequestTimeoutException.

    Defaults to using the client's configuration for com.twitter.finagle.service.TimeoutFilter.Param(timeout), which is typically set via com.twitter.finagle.param.CommonParams.withRequestTimeout.

    howLong

    how long, from the initial request issuance, an individual attempt given to complete. If it is not finite (e.g. Duration.Top), no method specific timeout will be applied.

    returns

    a new instance with all other settings copied

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. For example, a per-request timeout of 50 milliseconds:

      import com.twitter.conversions.time._
      import com.twitter.finagle.http.Http
      import com.twitter.util.Duration
      
      val client: Http.Client = ???
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withTimeoutPerRequest(50.milliseconds))
    See also

    withTimeoutTotal(Duration)

  25. def withTimeoutTotal(howLong: Tunable[Duration]): MethodBuilder

    Set a total timeout with a Tunable, including time spent on retries.

    Set a total timeout with a Tunable, including time spent on retries.

    If the request does not complete in this time, the response will be satisfied with a com.twitter.finagle.GlobalRequestTimeoutException.

    Defaults to using the client's configuration for com.twitter.finagle.service.TimeoutFilter.TotalTimeout(timeout).

    howLong

    how long, from the initial request issuance, is the request given to complete. If it is not finite (e.g. Duration.Top), no method specific timeout will be applied.

    returns

    a new instance with all other settings copied

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. For example, a total timeout of 200 milliseconds:

      import com.twitter.conversions.time._
      import com.twitter.finagle.http.Http
      import com.twitter.util.Duration
      import com.twitter.util.tunable.Tunable
      
      val client: Http.Client = ???
      val tunableTimeout: Tunable[Duration] = Tunable.const("id", 200.milliseconds)
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withTimeoutTotal(tunableTimeout))
    See also

    withTimeoutPerRequest(Tunable[Duration])

  26. def withTimeoutTotal(howLong: Duration): MethodBuilder

    Set a total timeout, including time spent on retries.

    Set a total timeout, including time spent on retries.

    If the request does not complete in this time, the response will be satisfied with a com.twitter.finagle.GlobalRequestTimeoutException.

    Defaults to using the client's configuration for com.twitter.finagle.service.TimeoutFilter.TotalTimeout(timeout).

    howLong

    how long, from the initial request issuance, is the request given to complete. If it is not finite (e.g. Duration.Top), no method specific timeout will be applied.

    returns

    a new instance with all other settings copied

    Definition Classes
    MethodBuilder → MethodBuilderScaladoc
    Example:
    1. For example, a total timeout of 200 milliseconds:

      import com.twitter.conversions.time._
      import com.twitter.finagle.http.Http
      import com.twitter.util.Duration
      
      val client: Http.Client = ???
      val builder = client.methodBuilder("inet!example.com:80")
      builder.withTimeoutTotal(200.milliseconds))
    See also

    withTimeoutPerRequest(Duration)

Inherited from MethodBuilderScaladoc[MethodBuilder]

Inherited from AnyRef

Inherited from Any

Ungrouped