title: How to combine CircuitBreaker with TimeLimiter and Bulkhead?
body: <p>I have a service that calls a dependency via REST. Service and dependency are part of a microservice architecture, so I'd like to use resilience patterns. My goals are:</p>
  
  <ul>
  <li>Have a circuit-breaker to protect the dependency when it's struggling</li>
  <li>Limit the time the call can run. The service has an SLA and has to answer in a certain time. On timeout we use the fallback value.</li>
  <li>Limit the number of concurrent calls to the dependency. Usually the rate of calls is low and the responses are fast, but we want to protect the dependency against bursts and queue requests inside the service.</li>
  </ul>
  
  <p>Below is my current code. It works, but ideally I'd like to use the <code>TimeLimiter</code> and <code>Bulkhead</code> classes as they seem to be built to work together.</p>
  
  <p>How can I write this better?</p>
  
  <pre class="lang-java prettyprint-override"><code>@Component
  class FooService(@Autowired val circuitBreakerRegistry: CircuitBreakerRegistry)
  {
      ...
  
      // State machine to take load off the dependency when slow or unresponsive
      private val circuitBreaker = circuitBreakerRegistry
          .circuitBreaker("fooService")
  
      // Limit parallel requests to dependency
      private var semaphore = Semaphore(maxParallelRequests)
  
      // The protected function
      private suspend fun makeHttpCall(customerId: String): Boolean {
          val client = webClientProvider.getCachedWebClient(baseUrl)
  
          val response = client
              .head()
              .uri("/the/request/url")
              .awaitExchange()
  
          return when (val status = response.rawStatusCode()) {
              200 -&gt; true
              204 -&gt; false
              else -&gt; throw Exception(
                  "Foo service responded with invalid status code: $status"
              )
          }
      }
  
      // Main function
      suspend fun isFoo(someId: String): Boolean {
          try {
              return circuitBreaker.executeSuspendFunction {
                  semaphore.withPermit {
                      try {
                          withTimeout(timeoutMs) {
                              makeHttpCall(someId)
                          }
                      } catch (e: TimeoutCancellationException) {
                          // This exception has to be converted because
                          // the circuit-breaker ignores CancellationException
                          throw Exception("Call to foo service timed out")
                      }
                  }
              }
          } catch (e: CallNotPermittedException) {
              logger.error { "Call to foo blocked by circuit breaker" }
          } catch (e: Exception) {
              logger.error { "Exception while calling foo service: ${e.message}" }
          }
  
          // Fallback
          return true
      }
  }
  </code></pre>
  
  <p>Ideally I'd like to write something like the <a href="https://resilience4j.readme.io/docs/getting-started-4#usage---flow" rel="nofollow noreferrer">docs</a> describe for Flows:</p>
  
  <pre class="lang-java prettyprint-override"><code>// Main function
  suspend fun isFoo(someId: String): Boolean {
      return monoOf(makeHttpCall(someId))
          .bulkhead(bulkhead)
          .timeLimiter(timeLimiter)
          .circuitBreaker(circuitBreaker)
  }
  </code></pre>