<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Aramburu</title>
    <description>The latest articles on DEV Community by Gabriel Aramburu (@gabrielaramburu).</description>
    <link>https://dev.to/gabrielaramburu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F916592%2F1a03fda6-25e3-4fde-bbe5-c585e28cc1bc.jpeg</url>
      <title>DEV Community: Gabriel Aramburu</title>
      <link>https://dev.to/gabrielaramburu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielaramburu"/>
    <language>en</language>
    <item>
      <title>Spring Cloud Loadbalancer with Eureka Server</title>
      <dc:creator>Gabriel Aramburu</dc:creator>
      <pubDate>Fri, 23 Sep 2022 20:43:37 +0000</pubDate>
      <link>https://dev.to/gabrielaramburu/spring-cloud-loadbalancer-with-eureka-server-4jhj</link>
      <guid>https://dev.to/gabrielaramburu/spring-cloud-loadbalancer-with-eureka-server-4jhj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I built a very simple application that takes advantage of the Eureka Discovery Service.&lt;/p&gt;

&lt;p&gt;It consists of a web application that needs to consume an external service in order to complete his work.&lt;/p&gt;

&lt;p&gt;At some point, there will be several service instances running on different machines. The web application uses Eureka  to discover the available service instances. &lt;/p&gt;

&lt;p&gt;The idea is to simulate an application that reacts to a high load situation, adding more services in order to maintain the response time under certain limits.&lt;/p&gt;

&lt;p&gt;I found some difficulties trying to build a version that works well under relatively high load so I will describe the solution that worked for me.&lt;/p&gt;

&lt;p&gt;I use Spring Cloud 2021.0.4 and Spring Boot 2.6.11 version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UK5d6d6u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nixi6hgt2zy9pawam9dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UK5d6d6u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nixi6hgt2zy9pawam9dx.png" alt="Image description" width="671" height="541"&gt;&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;When several service instances were running and processing the requests sent by the web application, If one of them was shut down the loadbalancer still sent requests to him. &lt;/p&gt;

&lt;p&gt;Therefore the application was not able to process the request and an error was sent to the client.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--68ktaJGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llstw70n70yrqn8aeiwy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--68ktaJGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llstw70n70yrqn8aeiwy.png" alt="Image description" width="880" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This graph belongs to &lt;a href="https://jmeter.apache.org/"&gt;JMeter&lt;/a&gt;, which was used to simulate concurrent application’s clients. &lt;/p&gt;

&lt;p&gt;The green line represents the number of failed transactions that the clients received after one of  the service instances was shut down. &lt;/p&gt;

&lt;p&gt;After several seconds the loadbalancer started to send requests to available service instances again and the problem was solved. &lt;/p&gt;
&lt;h2&gt;
  
  
  Expected behavior
&lt;/h2&gt;

&lt;p&gt;The loadbalancer executing in the web application should only send requests to available service instances.The client should not receive an error when a service instance is shut down.&lt;/p&gt;
&lt;h3&gt;
  
  
  First intent.
&lt;/h3&gt;

&lt;p&gt;The time period where the failed requests were registered corresponds to the loadbalancer cache time to live (ttl) configuration. So decreasing the cache refresh time improves the situation. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4_65meZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hl73pw3dzjvvtnfwgnpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4_65meZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hl73pw3dzjvvtnfwgnpa.png" alt="Image description" width="880" height="340"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nc"&gt;Configuration&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;web&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadbalancer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To decrease the loadbalancer cache expiration time seems to be a work around due to the fact that the loadbalancer should avoid sending requests to an unavailable instance even with an out of date cache.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Second intent.
&lt;/h3&gt;

&lt;p&gt;Another possible idea was to surround the RestTemplate call with a retry mechanism using a loop or an already retry implementation like Resilience4j, which is already integrated with Spring Boot.&lt;/p&gt;

&lt;p&gt;The problem with this approach is that the loadbalancer is a singleton component and shares the state with all the incoming requests.  &lt;/p&gt;

&lt;p&gt;When the balancer uses a Round Robin algorithm (even the problem applies to other implementations) there is no guarantee that when a request is sent to an unavailable instance the second try will not be processed for the same instance again and again. &lt;/p&gt;

&lt;p&gt;Actually with few service instances it is very easy to reproduce the problem. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B9pOjgue--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pi2keddhq3odumygbvzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B9pOjgue--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pi2keddhq3odumygbvzn.png" alt="Image description" width="641" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Third intent
&lt;/h3&gt;

&lt;p&gt;According to the Spring Cloud &lt;a href="https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#retrying-failed-requests"&gt;documentation&lt;/a&gt; we need to add a dependency to our web client application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zsQUri7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/568180ikj1y4rkhhguut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zsQUri7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/568180ikj1y4rkhhguut.png" alt="Image description" width="799" height="98"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;groupId&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;groupId&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;artifactId&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;artifactId&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When present, this retry implementation is used internally by the Spring Cloud loadbalancer component.&lt;/p&gt;

&lt;p&gt;Now, after running the first test again, the client does not get any error when a service instance is shut down. As the graph shows, the web application throughput was affected for a moment, but at least the client did not receive any failed request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jiMWdhHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abh5sb1c1nfxnpyr7iyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jiMWdhHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abh5sb1c1nfxnpyr7iyc.png" alt="Image description" width="835" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the metrics show, the loadbalancer still is sending request to the unavailable instance, but at least  in conjunction with Spring Retry is able to deal  with the ConnectionException in a more accurate way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9qqjs7wR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xecg48d91so9ttd84afm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9qqjs7wR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xecg48d91so9ttd84afm.png" alt="Image description" width="656" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, the solution that worked better for me was to disable the LoadBalancer cache an to increase the retries max to three.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadbalancer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadbalancer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;retries&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It is mandatory to include the Spring Retry dependency in order to improve the resilience of the Spring Cloud loadbalancer implementation.&lt;/p&gt;

</description>
      <category>java</category>
      <category>microservices</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Bulkhead pattern: semaphore vs threadPool</title>
      <dc:creator>Gabriel Aramburu</dc:creator>
      <pubDate>Mon, 29 Aug 2022 17:16:00 +0000</pubDate>
      <link>https://dev.to/gabrielaramburu/bulkhead-pattern-semaphore-vs-threadpool-226p</link>
      <guid>https://dev.to/gabrielaramburu/bulkhead-pattern-semaphore-vs-threadpool-226p</guid>
      <description>&lt;h2&gt;
  
  
  Why two different implementations?
&lt;/h2&gt;

&lt;p&gt;In this article I will refer to Spring and Resilence4j.&lt;/p&gt;

&lt;p&gt;If you are reading this article you probably already know about the bulkhead pattern, what is the problem that  it intends to solve and the most common implementations: semaphore based and threadPool based.&lt;/p&gt;

&lt;p&gt;At least for me, it was not easy to realize when to use a semaphore implementation and when to use a  threadPool one. &lt;/p&gt;

&lt;p&gt;I know how a Semaphore works, and I also understand the ThreadPool pattern, therefore a  short answer and the most obvious could have been: use a threadPool for limiting the number of asynchronous calls and use a semaphore for limiting  synchronous ones.&lt;/p&gt;

&lt;p&gt;So why was the difficult part? The reason was these questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Why not just combine @Async with a bulkhead semaphore based implementation?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can both annotations be used together? If yes, why is the reason for a threadPool implementation?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  @Async and @Bulkhead combined.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Bulkhead&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Service3"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"futureFallback"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Async&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doSomeWork&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Excecuting service 3 - "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;   
        &lt;span class="nc"&gt;Util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mockExternalServiceHttpCall&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DELAY&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;completedFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ok"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/gabrielaramburu/bulkhead-patttern-in-action/tree/main/bulkhead-threadPool-semaphore" rel="noopener noreferrer"&gt;Complete Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yes, you can use both annotations together. They allow you to generate a limited number of async calls based on your bulkhead semaphore configuration.&lt;/p&gt;

&lt;p&gt;However, there are some implications that are useful to know.&lt;/p&gt;

&lt;h3&gt;
  
  
  SimpleAsyncTaskExecutor.
&lt;/h3&gt;

&lt;p&gt;When you annotate a method with the @Async annotation, Spring can use different implementations of the &lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskExecutor.html" rel="noopener noreferrer"&gt;TaskExecutor&lt;/a&gt; interface.&lt;br&gt;
By default, the framework uses the &lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/SimpleAsyncTaskExecutor.html" rel="noopener noreferrer"&gt;SimpleAsyncTaslExecutor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This implementation will create a new thread each time the annotated method is invoked; this thread will not be reused. &lt;/p&gt;

&lt;p&gt;The problem with this approach is that you will create a new thread even if the semaphore counter is 0 (bulkhead is full)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9snzm8r5ll1yag9n5c1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9snzm8r5ll1yag9n5c1l.png" alt="plantUml"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the following stacktrace, the framework first creates a thread and then calls the bulkhead pattern which determines if there are available permissions to continue the execution. If the semaphore counter is cero, the bulkhead will reject the method execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;_simpleAsyncTask1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Suspended&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;breakpoint&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;Service3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;  
    &lt;span class="nc"&gt;Service3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doSomeWork&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;  
    &lt;span class="nc"&gt;Service3&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;$FastClassBySpringCGLIB&lt;/span&gt;&lt;span class="err"&gt;$$&lt;/span&gt;&lt;span class="mi"&gt;6085&lt;/span&gt;&lt;span class="n"&gt;f5a4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;    
    &lt;span class="nc"&gt;MethodProxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;218&lt;/span&gt;  
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invokeJoinpoint&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;793&lt;/span&gt; 
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReflectiveMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;163&lt;/span&gt; 
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;763&lt;/span&gt; 
    &lt;span class="nc"&gt;MethodInvocationProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;89&lt;/span&gt;  
    &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$handleJoinPointCompletableFuture&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;225&lt;/span&gt; 
    &lt;span class="mi"&gt;1457434357&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;    
    &lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$decorateCompletionStage&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; 
    &lt;span class="mi"&gt;1251257755&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;    
    &lt;span class="nf"&gt;SemaphoreBulkhead&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;executeCompletionStage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;557&lt;/span&gt;  
    &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleJoinPointCompletableFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;223&lt;/span&gt;    
    &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;162&lt;/span&gt;   
    &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$bulkheadAroundAdvice&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;eb13a26&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;129&lt;/span&gt;   
    &lt;span class="mi"&gt;1746723773&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;  
    &lt;span class="mi"&gt;1746723773&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CheckedFunction0&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;).&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$andThen$ca02ab3&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CheckedFunction1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;265&lt;/span&gt;    
    &lt;span class="mi"&gt;1151489454&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;  
    &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeFallBack&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CheckedFunction0&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;139&lt;/span&gt; 

&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
 &lt;span class="nc"&gt;BulkheadAspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bulkheadAroundAdvice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bulkhead&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;   
    &lt;span class="nc"&gt;NativeMethodAccessorImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke0&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kd"&gt;native&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;  
    &lt;span class="nc"&gt;NativeMethodAccessorImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;  
    &lt;span class="nc"&gt;DelegatingMethodAccessorImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;  
    &lt;span class="nc"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;...)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;566&lt;/span&gt;  
    &lt;span class="nc"&gt;AspectJAroundAdvice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AbstractAspectJAdvice&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;invokeAdviceMethodWithGivenArgs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;634&lt;/span&gt;  
    &lt;span class="nc"&gt;AspectJAroundAdvice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AbstractAspectJAdvice&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;invokeAdviceMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JoinPoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JoinPointMatch&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;624&lt;/span&gt;   
    &lt;span class="nc"&gt;AspectJAroundAdvice&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MethodInvocation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;   
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReflectiveMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt; 
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;763&lt;/span&gt; 
    &lt;span class="nc"&gt;ExposeInvocationInterceptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MethodInvocation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt;   
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReflectiveMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;186&lt;/span&gt; 
    &lt;span class="nc"&gt;CglibAopProxy&lt;/span&gt;&lt;span class="n"&gt;$CglibMethodInvocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;763&lt;/span&gt; 
    &lt;span class="nc"&gt;AnnotationAsyncExecutionInterceptor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AsyncExecutionInterceptor&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$invoke&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MethodInvocation&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;115&lt;/span&gt;  
    &lt;span class="mi"&gt;1466446116&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;   
    &lt;span class="nc"&gt;AsyncExecutionAspectSupport&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$doSubmit&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Callable&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;278&lt;/span&gt;   
    &lt;span class="mi"&gt;409592088&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; 
    &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="n"&gt;$AsyncSupply&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;1700&lt;/span&gt;   

    &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
&lt;span class="nc"&gt;SimpleAsyncTaskExecutor&lt;/span&gt;&lt;span class="n"&gt;$ConcurrencyThrottlingRunnable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;286&lt;/span&gt;   
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="nl"&gt;line:&lt;/span&gt; &lt;span class="mi"&gt;829&lt;/span&gt;  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing a load test that invokes for 60 seconds an @Aync and @Bulkhead annotated method, you can see from a profiling &lt;a href="https://visualvm.github.io/" rel="noopener noreferrer"&gt;tool&lt;/a&gt; picture, that the application only used 34 out of 514 created threads. This obviously represents a waste of resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6e8rbdo290kvh86688yy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6e8rbdo290kvh86688yy.png" alt="test1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ThreadPoolTaskExecutor
&lt;/h3&gt;

&lt;p&gt;Another option could be to use the TreadPoolTaskExecutor implementation.&lt;br&gt;
After executing the same test using this implementation, the number of created threads decreased a lot (41).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9k9v2wornideucl790c9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9k9v2wornideucl790c9.png" alt="test2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the problem with this approach is that we are using unnecessary redundancy. Using a thread pool and a semaphore together, in my opinion, has no real advantage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;For limiting asynchronous calls, use a Bulkhead threadPool implementation instead of a combination of @Async and Bulkhead semaphore.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
