jado
jado

Reputation: 104

Re-establish TCP connection on HTTP 503

We use okhttp in our Java apps deployed on k8s cluster. Our source app doesn't have istio enabled and connects to destination with envoy sidecar. Connectivity chain looks like this:

SRC --------> Envoy -> DST

So in fact SRC app establish a connection not directly to DST app, but to Envoy proxy in front of it. When DST apps shuts down, it terminates all the connection between DST and Envoy, but connections between SRC and Envoy remains open. That's why SRC app starts to receive 503 errors. Another message from SRC to DST also gets 503 because we keep reusing idle connection established in connection pool of okhttp. Solution to this problem is to reestablish new TCP connection instead of use one of the idle connections from connection pool. Is it possible to configure okhttp to terminate whole TCP connection based on single HTTP 503 received?

Upvotes: 1

Views: 694

Answers (2)

Julien Vermillard
Julien Vermillard

Reputation: 3033

Here is what I use in Java 17

private final OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(c -> {
    var response = c.proceed(c.request());
    if (response.code() == 503) {
        c.connection().socket().close();
    }
    return response;
}).build();

Upvotes: 0

Yuri Schimke
Yuri Schimke

Reputation: 13458

Something like this should work

import okhttp3.OkHttpClient
import okhttp3.Request

fun main() {
  val client = OkHttpClient.Builder()
    .eventListenerFactory(LoggingEventListener.Factory())
    .addNetworkInterceptor { chain ->
      chain.proceed(chain.request()).also { response ->
        println(response.code)
        if (response.code == 503) {
          println("closing")
          chain.connection()?.socket()?.close()
        }
      }
    }
    .build()

  val response1 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()

  val response2 = client.newCall(Request.Builder().url("https://httpbin.org/status/503").build()).execute()

  val response3 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()
}

Upvotes: 0

Related Questions