<?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: CherryChain</title>
    <description>The latest articles on DEV Community by CherryChain (@cherrychain).</description>
    <link>https://dev.to/cherrychain</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%2Forganization%2Fprofile_image%2F2331%2Fef89ddea-2095-4729-a576-ea494e61ef22.png</url>
      <title>DEV Community: CherryChain</title>
      <link>https://dev.to/cherrychain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cherrychain"/>
    <language>en</language>
    <item>
      <title>
Vert.x Circuit Breaker</title>
      <dc:creator>Stanislav Petrosyan</dc:creator>
      <pubDate>Fri, 28 May 2021 14:56:37 +0000</pubDate>
      <link>https://dev.to/cherrychain/vert-x-circuit-breaker-pattern-19pe</link>
      <guid>https://dev.to/cherrychain/vert-x-circuit-breaker-pattern-19pe</guid>
      <description>&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;We can imagine a scenario where we have a restaurant. We have the kitchen service and the orders service that communicate with each other. When a new order arrives, this will be sent to the kitchen, which gets to work and prepares the dishes. When the dishes are ready, they are delivered to the customer. But if we suppose that a really large number of customers come, so consequently a large number of orders, the kitchen gets overloaded by all these orders and therefore it cannot prepare the dishes at the same rate as the orders arrive. At this point the customers are going to wait much time before receiving their dishes because the kitchen is using all the resources for the previous orders.&lt;br&gt;
So we have a deadlock. To make the situation worse, we can immagine that the chef, due to the excessive work, has cut themself and for some time they cannot work.&lt;br&gt;
The scenario just described is defined as &lt;code&gt;cascading failure&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A definition that we can give of a cascading failure is: a process in a system of interconnected parts in which the failure of one or few parts can trigger the failure of other parts and so on. Such a failure may happen in many types of systems, including power transmission, computer networking, finance, transportation systems, organisms, the human body, and ecosystems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Explore the pattern
&lt;/h2&gt;

&lt;p&gt;The Circuit Breaker Pattern is one solution for the &lt;code&gt;cascading failure&lt;/code&gt;. This pattern can prevent an application from repeatedly trying to execute an operation that is likely to fail. Allowing it to continue without waiting for the fault to be fixed. The Circuit Breaker pattern also enables an application to detect whether the fault has been resolved. If the problem appears to have been fixed, the application can try to invoke the operation.&lt;/p&gt;

&lt;p&gt;In the previous scenario the circuit breaker is applied to the orders service: every time a new customer comes, the orders service asks the kitchen if it can prepare the dish in a short time. If the kitchen's response is negative, the orders service consider it as a failure and so it understands that the kitchen service is broken and advises the new customer to have a drink at the bar service in order to not overload the kitchen's one.&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%2Fwhoiv71hy6pppgga8ujp.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%2Fwhoiv71hy6pppgga8ujp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So a circuit breaker acts as a proxy for operations that might fail. The proxy should monitor the number of recent failures that have occurred and use this information to decide whether to allow the operation to proceed, or simply return an exception immediately.&lt;/p&gt;

&lt;p&gt;In this article we see how to use an implentation of this pattern: &lt;code&gt;Vertx Circuit Breaker&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To use the Vert.x Circuit Breaker, add the following dependency to the dependencies section of your build descriptor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maven (in your &lt;strong&gt;pom.xml&lt;/strong&gt;)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.vertx&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;vertx-circuit-breaker&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.0.3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Gradle (in your &lt;strong&gt;build.gradle&lt;/strong&gt; file):
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;compile&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;breaker:&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So now you can use a circuit breaker in your java/kotlin file, here is an example in kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;breaker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreakerOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxFailures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxRetries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setResetTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t recreate a circuit breaker on every call. A circuit breaker is a stateful entity. It is recommended to store the circuit breaker instance in a class field.&lt;/p&gt;

&lt;p&gt;Inside CircuitBreakerOptions we can set some settings: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setMaxFailures: number of failures before opening the circuit&lt;/li&gt;
&lt;li&gt;setTimeout: consider a failure if the operation does not succeed in time&lt;/li&gt;
&lt;li&gt;setMaxRetries: number of retries if the operation fails&lt;/li&gt;
&lt;li&gt;setResetTimeout: time to wait for switch from OPEN to HALF OPEN state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For executing code with the circuit breaker we just use &lt;code&gt;execute&lt;/code&gt; function. &lt;br&gt;
The executed block receives a &lt;code&gt;Future&lt;/code&gt; object as parameter, to denote the success or failure of the operation as well as the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// we set promise type to String&lt;/span&gt;
&lt;span class="n"&gt;breaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;// some code executing with the breaker&lt;/span&gt;
  &lt;span class="c1"&gt;// the code reports failures or success on the given promise.&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;onComplete&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Get the operation result.&lt;/span&gt;
  &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stuff done"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see how it works this circuit breaker.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Machine
&lt;/h2&gt;

&lt;p&gt;The circuit breaker uses a state machine for registering all events and behave accordingly. &lt;br&gt;
Below we can see an image of this state machine.&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%2F9r39o6pkctws1pjbe9h3.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%2F9r39o6pkctws1pjbe9h3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Circuit Breaker goes into the &lt;strong&gt;OPEN&lt;/strong&gt; state when the service is failed&lt;/li&gt;
&lt;li&gt;Circuit Breaker goes into the &lt;strong&gt;CLOSE&lt;/strong&gt; state when the service it works correctly&lt;/li&gt;
&lt;li&gt;Circuit Breaker goes into the &lt;strong&gt;HALF OPEN&lt;/strong&gt; state when the &lt;code&gt;reset timeout&lt;/code&gt; is expired&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Open state
&lt;/h3&gt;

&lt;p&gt;When a circuit is in the open state, it means that no code inside an &lt;code&gt;execute&lt;/code&gt; block will be ran for the same instance. &lt;br&gt;
The circuit opens when the maxFailures property is satisfied. &lt;/p&gt;

&lt;p&gt;Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;circuitBreaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;onComplete&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can declare a &lt;code&gt;failure&lt;/code&gt; when an execution block fails independently of how many calls fail inside that block. In this case the count of failure will be set to 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Close state
&lt;/h3&gt;

&lt;p&gt;When a circuit is in the closed state, it means that the number of failures is less than the maximum. In this state all code will be executed inside the &lt;code&gt;execute&lt;/code&gt; block. &lt;/p&gt;

&lt;p&gt;In this state it is possible to define the &lt;code&gt;retry&lt;/code&gt; number (retries are available just when the circuit is in the closed state). This number specifies how many times the circuit may execute the code before failing. So for example, if we have setMaxRetries to 2, the operation may be called 3 times: the initial attempt plus 2 retries. So at the end of the third call that executed block fails and will increment the number of failures by 1. &lt;/p&gt;

&lt;p&gt;Retries can be useful when the answer is not deterministic. In fact, we can take advantage of our scenario by imagining that the order service asks if the dish is ready in the kitchen. This request has an nondeterministic answer as, depending on the moment, different answers can be received. In fact, if the kitchen is busy and the dish is not ready, you may not receive a response, thus sending the request to timeout and creating a failure. Otherwise, if the kitchen has finished, the answer will be successful so the dish will be delivered to the customer. We don't want the first situation to happen because the circuit breaker would immediately count the failure, instead we want to make several calls because we assume that the resource we want takes a longer time to be ready. So we set up retries for this very reason. If in the end the resource is still not available then we will be sure that there is a problem and we will activate the circuit breaker. &lt;/p&gt;

&lt;p&gt;By default the timeout between retries is set to 0 which means that retries will be executed one after another without any delay. This, however, will result in increased load on the called service and may delay its recovery. In order to mitigate this problem it is recommended to execute retries with delays.&lt;br&gt;
The &lt;code&gt;retryPolicy&lt;/code&gt; method can be used to specify retry policy. Retry policy is a function which receives retry count as a single argument and returns the timeout in milliseconds before retry is executed and allows to implement a more complex policy. Below is an example of retry timeout which grows linearly with each retry count:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;circuitBreaker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-circuit-breaker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreakerOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxFailures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxRetries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;retryPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retryCount&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;retryCount&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Half open state
&lt;/h3&gt;

&lt;p&gt;When a circuit is in the open state, every call that you want to &lt;code&gt;execute&lt;/code&gt; will fail, without executing really the code. At this point, after some time (called &lt;code&gt;ResetTimeout&lt;/code&gt;) which by default is set to 30000 ms, the circuit will be set to half open state. In this state the next execution of protected code will define the next state of circuit. If execution succeeds then the state will be set to closed otherwise it will be set to open.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Bus
&lt;/h3&gt;

&lt;p&gt;Every time that the state of circuit changes, an event is published on the event bus. The address of the bus can be configured using &lt;code&gt;setNotificationAddress&lt;/code&gt;. If null is passed to this method, the notifications will be disabled. By default, the used address is &lt;strong&gt;vertx.circuit-breaker&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each message contains at least: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For doing this you just need few row of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;localConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"vertx.circuit-breaker"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handlers
&lt;/h3&gt;

&lt;p&gt;It is possible to configure some callbacks when circuit changes the state. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;breaker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-circuit-breaker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreakerOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxFailures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;openHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Circuit opened"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;closeHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Circuit closed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;halfOpenHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Circuit half-opened"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In conclusion this pattern is great when you have a system with a large number of service calls which are used to manage a large number of resources. &lt;/p&gt;

&lt;p&gt;So as a last tip we recommend to use this pattern to prevent an application from trying to invoke a remote service or access a shared resource if this operation is highly likely to fail. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't use this pattern as a replacement for exception handling in your application business logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you can implement circuit breaker in your project. :) &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>vertx</category>
      <category>circuitbreaker</category>
      <category>pattern</category>
    </item>
    <item>
      <title>JavaFX, JLink and JPackage</title>
      <dc:creator>Luca Guadagnini</dc:creator>
      <pubDate>Thu, 25 Mar 2021 16:57:25 +0000</pubDate>
      <link>https://dev.to/cherrychain/javafx-jlink-and-jpackage-h9</link>
      <guid>https://dev.to/cherrychain/javafx-jlink-and-jpackage-h9</guid>
      <description>&lt;p&gt;A few days ago, for the &lt;em&gt;Java User Group Trentino-Alto Adige-Südtirol&lt;/em&gt; I shown some experiments on &lt;strong&gt;JavaFx&lt;/strong&gt;, &lt;strong&gt;JLink&lt;/strong&gt; and &lt;strong&gt;JPackage&lt;/strong&gt;. The purpose of the talk was to show the chance to use JavaFX working with new JDK tools such as JLink (since OpenJDK 9) and JPackage (provided by the new OpenJDK 16) for rich client development.&lt;br&gt;
Although some may state «&lt;em&gt;JavaFX is dead&lt;/em&gt;» since it's not part of the &lt;strong&gt;OpenJDK&lt;/strong&gt; anymore, JavaFX is actually alive and kicking. &lt;strong&gt;OpenJFX&lt;/strong&gt; (aka Open JavaFX) is a side project still maintained and evolved by Oracle, Gluon, BellSoft and others. Suddenly, because of the advent of OpenJDK, Adoptium and other free OpenJDK builds, it may not be that straightforward to understand how to get started with JavaFX, especially if you still working on an Oracle Jave SE 1.8.0 distribution. Let's try to get there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before starting
&lt;/h2&gt;

&lt;p&gt;To grasp the example, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apache Maven&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sdkman&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;a Linux shell or a Wsl2 shell for Windows (sorry I know nothing about MacOS)&lt;/li&gt;
&lt;li&gt;an editor for the pom file (even &lt;code&gt;Vim&lt;/code&gt; is fine, but I don't remember how to exit from it, so don't ask me).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;&lt;br&gt;
Keep in mind that I will write regarding &lt;code&gt;module-info&lt;/code&gt; and &lt;strong&gt;Java Platform Module System&lt;/strong&gt;, but I won't explain too much about them.&lt;br&gt;
The goal of this post is not about how you have to organize a project, but how to make the tools work for you. I will instead write something more about JPMS in a future post (it is quite intriguing and intricated).&lt;/p&gt;

&lt;h2&gt;
  
  
  What is JavaFX?
&lt;/h2&gt;

&lt;p&gt;JavaFX is a framework of graphics and media packages that enables developers to create and deploy rich client applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's take a basic JavaFX example, for instance, this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/lucaguada/treefx" rel="noopener noreferrer"&gt;https://gitlab.com/lucaguada/treefx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The source code is pretty old and is a JavaFX 2.1 example taken from here: &lt;a href="https://docs.oracle.com/javafx/2/animations/basics.htm" rel="noopener noreferrer"&gt;Oracle Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I configured the &lt;code&gt;pom.xml&lt;/code&gt; as simple as possible, or at least this was my intention. I just set two plugins: &lt;code&gt;maven-compiler-plugin&lt;/code&gt; to avoid compilation issues when we advance the Java version during our tests and &lt;code&gt;exec-maven-plugin&lt;/code&gt; for being able to run our application from the terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oracle Java SE to OpenJDK
&lt;/h2&gt;

&lt;p&gt;As I mentioned before, JavaFX is not part of the OpenJDK anymore. Let's see if such a boomer like me is correct.&lt;/p&gt;

&lt;p&gt;Download the &lt;code&gt;tar.gz&lt;/code&gt; file of Oracle Java SE 1.8.0 from here: &lt;a href="https://www.oracle.com/java/technologies/javase-downloads.html" rel="noopener noreferrer"&gt;Oracle Java&lt;/a&gt; and don't worry about the license, the FAQ explicitly states this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Oracle Java SE8 updates, which includes the Oracle JRE with Java Web Start, continue to be free for personal use, development, testing, prototyping, demonstrating and some other important uses explained in this FAQ under the OTN License Agreement for Java SE. Personal users can continue downloading the Oracle Java SE 8 JRE at java.com.


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

&lt;/div&gt;

&lt;p&gt;Unzip the package in the &lt;code&gt;.sdkman/candidates/java&lt;/code&gt; folder. You should be able to check the OracleJDK by typing:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;sdk list java


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

&lt;/div&gt;

&lt;p&gt;Sdkman should list the Oracle Java SE as follow:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Unclassified  |     | 8.0.281      | none    | &lt;span class="nb"&gt;local &lt;/span&gt;only | 8.0.281-oracle


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

&lt;/div&gt;

&lt;p&gt;Nice! Therefore we can now compile our project:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;sdk use java 8.0.281-oracle
Using java version 8.0.281-oracle &lt;span class="k"&gt;in &lt;/span&gt;this shell.
 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile &lt;span class="nb"&gt;exec&lt;/span&gt;:java


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

&lt;/div&gt;

&lt;p&gt;and if everything is fine:&lt;br&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%2Fdwmoh0n8legdqc5x0gkj.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%2Fdwmoh0n8legdqc5x0gkj.png" alt="TreeFX in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice twice! However, we don't want to have a headache for Oracle licenses/subscriptions/etc., so we now change the OracleJDK with an Open one and compile again.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;sdk &lt;span class="nb"&gt;install &lt;/span&gt;java 8.0.272.hs-adpt
... &lt;span class="nb"&gt;install &lt;/span&gt;process by sdkman ...
 &lt;span class="nv"&gt;$ &lt;/span&gt;sdk use java 8.0.272.hs-adpt
Using java version 8.0.272.hs-adpt &lt;span class="k"&gt;in &lt;/span&gt;this shell.
 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile &lt;span class="nb"&gt;exec&lt;/span&gt;:java


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

&lt;/div&gt;

&lt;p&gt;and tragically:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException


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

&lt;/div&gt;

&lt;p&gt;Errors, errors everywhere! TreeFX can't find any package of the framework JavaFX! How to solve this? JavaFX is now a set of self-contained dependencies, so let's modify the &lt;code&gt;pom.xml&lt;/code&gt; file by defining the right dependencies.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.openjfx&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;javafx-controls&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;16&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.openjfx&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;javafx-media&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;16&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;and then compile again. But... again...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project treefx: Compilation failure
[ERROR] /home/.../treefx/src/main/java/io/trydent/treefx/Flower.java:[7,20] cannot access javafx.scene.Group
[ERROR]   bad class file: /home/.../.m2/repository/org/openjfx/javafx-graphics/16/javafx-graphics-16-linux.jar(javafx/scene/Group.class)
[ERROR]     class file has wrong version 55.0, should be 52.0
[ERROR]     Please remove or make sure it appears in the correct subdirectory of the classpath.


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

&lt;/div&gt;

&lt;p&gt;No more errors about missing packages, but class file version! What does it mean? Every time the Java Compiler compiles your code, it annotates your classes with a number to identify the target JDK release. In this case, the class version 55.0 targets JDK 11, but we're using JDK 8, therefore the class version number should be at a maximum of 52.0.&lt;/p&gt;

&lt;p&gt;Unfortunately, there is no way to downgrade JavaFX to a version compatible with JDK 8. Sure, as someone already suggested to me, we can download &lt;strong&gt;Liberica OpenJDK 8 with JavaFX&lt;/strong&gt; (or the Azul one) however, we will be forever stuck to JavaFX 8. Being locked to JavaFX 8 doesn't allow us to benefit from having bug fixes and other kinds of improvements.&lt;/p&gt;

&lt;p&gt;It's time to upgrade our OpenJDK to 11.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenJDK 11
&lt;/h2&gt;

&lt;p&gt;Once we set our JavaFX dependencies in the &lt;code&gt;pom.xml&lt;/code&gt;, we can try to switch to an OpenJDK 11:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;sdk use java 11.0.10.hs-adpt
Using java version 11.0.10.hs-adpt &lt;span class="k"&gt;in &lt;/span&gt;this shell.
 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile &lt;span class="nb"&gt;exec&lt;/span&gt;:java


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

&lt;/div&gt;

&lt;p&gt;And everything will be fine. No more errors about missing packages and class versions.&lt;/p&gt;

&lt;p&gt;Because our application is ready, we can package it into a self-executable-jar and release it to our customers/friends/pets (well, if they are all interested in Tree animations, of course). By doing so, we face an old-fashioned issue: we depend on the customer/friend/pet's installed JDK. We can't upgrade our development JDK (let's think about new API's and runtime improvements, etc.) until our customers don't upgrade their own. Yes, we could package the application with a JRE, but this would lead to having a pretty big sized ZIP for just one animation.&lt;/p&gt;

&lt;h2&gt;
  
  
  JLink, the Java Linker
&lt;/h2&gt;

&lt;p&gt;As explained in JEP 282, &lt;strong&gt;JLink&lt;/strong&gt; is a tool that can assemble modules and their dependencies into a custom Java runtime image. Since the JRE, JDK and &lt;strong&gt;some&lt;/strong&gt; libraries/frameworks are now restructured in modules, we can create a custom JRE image for our wonderful JavaFX application!&lt;/p&gt;

&lt;p&gt;JavaFX is indeed modularized, so we can try!&lt;/p&gt;

&lt;p&gt;Before starting, though, I have to inform you that I skipped the official &lt;em&gt;Maven JLink Plugin&lt;/em&gt; usage. In a draft of this article, I  explained how to work with the JLink plugin and JavaFX, but I realized it was far too long and not very useful in practice (for this example, at least). Instead of the Maven JLink Plugin, we'll use the official &lt;em&gt;JavaFX JLink Plugin&lt;/em&gt; provided by the JavaFX development team to simplify the process.&lt;/p&gt;

&lt;p&gt;Let us modify the &lt;code&gt;pom.xml&lt;/code&gt; and append a Maven plugin for &lt;strong&gt;JavaFX and JLink&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.openjfx&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;javafx-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;compress&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/compress&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;noHeaderFiles&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/noHeaderFiles&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;stripDebug&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/stripDebug&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;noManPages&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/noManPages&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;launcher&amp;gt;&lt;/span&gt;treefx&lt;span class="nt"&gt;&amp;lt;/launcher&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;treefx/com.acme.treefx.TreeFX&lt;span class="nt"&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;jlinkImageName&amp;gt;&lt;/span&gt;treefx&lt;span class="nt"&gt;&amp;lt;/jlinkImageName&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;jlinkZipName&amp;gt;&lt;/span&gt;treefx&lt;span class="nt"&gt;&amp;lt;/jlinkZipName&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The configuration is not quite self-explanatory, here some hints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;compress&lt;/em&gt; enables compression of resources, we set to 2 for compressing to ZIP&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;noHeaderFiles&lt;/em&gt; excludes C header files for supporting native-code programming (we don't need that for our custom JRE) &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;stripDebug&lt;/em&gt; excludes JRE debug information (yeah we don't need this too)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;noManPages&lt;/em&gt; excludes the JDK docs&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;jlinkImageName&lt;/em&gt; the runtime final name&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;jlinkZipName&lt;/em&gt; the ZIP final name&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;launcher&lt;/em&gt; the executable name&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;mainClass&lt;/em&gt; what &lt;code&gt;main&lt;/code&gt; needs to be launched by specifying module, package and class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We set all such exclusions for shrinking our custom JRE to a smaller size than the usual one.&lt;br&gt;
However, if we try the new plugin command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile javafx:jlink


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

&lt;/div&gt;

&lt;p&gt;Something is still missing:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[ERROR] Failed to execute goal org.openjfx:javafx-maven-plugin:0.0.5:jlink (default-cli) on project treefx: Error: jlink requires a module descriptor


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

&lt;/div&gt;

&lt;p&gt;As I said before if JDK, JRE and JavaFX are now modularized, this implies that we need to modularize our application too. Create a new file named &lt;code&gt;module-info.java&lt;/code&gt; in the folder &lt;code&gt;src/main/java&lt;/code&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;module&lt;/span&gt; &lt;span class="n"&gt;treefx&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="n"&gt;javafx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;controls&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="n"&gt;javafx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;opens&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;acme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;treefx&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;javafx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;graphics&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;The file defines our application as a module named &lt;code&gt;treefx&lt;/code&gt; and our module requires some modules as well in order to work, &lt;code&gt;javafx.controls&lt;/code&gt; and &lt;code&gt;javafx.media&lt;/code&gt;.&lt;br&gt;
I don't want to explain too much about it, but keep in mind that &lt;em&gt;modules are a new way to organize your applications and libraries and enable strong encapsulation and implementation/reflection hiding&lt;/em&gt;. Knowing this, what about that last statement &lt;code&gt;opens&lt;/code&gt; in &lt;code&gt;module-info&lt;/code&gt;?&lt;br&gt;
There are some cases where you have to enable reflection (because of modules, reflection is inaccessible by default) for your classes, because of frameworks for instance. In our case we have to enable the reflection of our package &lt;code&gt;com.acme.treefx&lt;/code&gt; to the module &lt;code&gt;javafx.graphics&lt;/code&gt; to let JavaFX work.&lt;/p&gt;

&lt;p&gt;Then once again:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile javafx:jlink


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

&lt;/div&gt;

&lt;p&gt;... finally ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[INFO] Building zip: /home/.../treefx/target/treefx.zip


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

&lt;/div&gt;

&lt;p&gt;Yeeeah our application is ready to be propagated to Knowhere (cit.)!&lt;/p&gt;

&lt;p&gt;Let's take a look at what actually happened in the target folder:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;tree target/treefx


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

target/treefx
├── bin
│   ├── java
│   ├── keytool
│   └── treefx
├── conf
│   ├── [...]
├── legal
│   ├── [...]
├── lib
│   ├── [...]
└── release


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

&lt;/div&gt;

&lt;p&gt;What do we have in the generated &lt;code&gt;treefx.zip&lt;/code&gt;? As we can see, it's just a JRE with our application encapsulated inside. In folder &lt;code&gt;bin&lt;/code&gt;, we can find the launcher &lt;code&gt;treefx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And the size of the ZIP file? Just &lt;em&gt;47Mb&lt;/em&gt;! The best part? If our application only needs the modules we declared in &lt;code&gt;module-info&lt;/code&gt;, the size will increase only if our application grows in terms of compiled classes.&lt;/p&gt;

&lt;p&gt;Nice trice, right? But we want more! For the sake of aesthetics, we prefer to distribute our application with an official &lt;code&gt;deb&lt;/code&gt; package how can we do this?&lt;/p&gt;

&lt;p&gt;It's time to upgrade our OpenJDK to 16!&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenJDK 16 and JPackage
&lt;/h2&gt;

&lt;p&gt;OpenJDK 16 has been released on 16th March. However, this is not the right post to talk about all the new shining features and tools, but it is the right post to talk about a new particular tool: &lt;strong&gt;JPackage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;JPackage was introduced as an incubating tool from JDK 14 to JDK 15 and is now production-ready for packaging self-contained Java applications.&lt;/p&gt;

&lt;p&gt;As above we want to rely on Maven and fortunately, we got a well-packed plugin (&lt;a href="https://github.com/petr-panteleyev/jpackage-maven-plugin" rel="noopener noreferrer"&gt;JPackage Plugin&lt;/a&gt;)  on Maven Central that we can add:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.panteleyev&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jpackage-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.4.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;TreeFX&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;appVersion&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/appVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;vendor&amp;gt;&lt;/span&gt;com.acme&lt;span class="nt"&gt;&amp;lt;/vendor&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;destination&amp;gt;&lt;/span&gt;target/dist&lt;span class="nt"&gt;&amp;lt;/destination&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;module&amp;gt;&lt;/span&gt;treefx/com.acme.treefx.TreeFX&lt;span class="nt"&gt;&amp;lt;/module&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;runtimeImage&amp;gt;&lt;/span&gt;target/treefx&lt;span class="nt"&gt;&amp;lt;/runtimeImage&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;linuxShortcut&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/linuxShortcut&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;linuxPackageName&amp;gt;&lt;/span&gt;treefx&lt;span class="nt"&gt;&amp;lt;/linuxPackageName&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;linuxAppCategory&amp;gt;&lt;/span&gt;Utilities&lt;span class="nt"&gt;&amp;lt;/linuxAppCategory&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;linuxMenuGroup&amp;gt;&lt;/span&gt;Utilities&lt;span class="nt"&gt;&amp;lt;/linuxMenuGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;icon&amp;gt;&lt;/span&gt;${project.basedir}/duke.png&lt;span class="nt"&gt;&amp;lt;/icon&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;javaOptions&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;-Dfile.encoding=UTF-8&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/javaOptions&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;I have to spend some words about the configuration because it's a little bit tricky on some points.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy part&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;name&lt;/em&gt; sets the application name (you don't say!)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;appVersion&lt;/em&gt; as any other application, our TreeFX has a release version too!&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;vendor&lt;/em&gt; sets the vendor or our Acme company&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;destination&lt;/em&gt; sets the destination folder for the generated package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tricky part&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;module&lt;/em&gt; we set the module and the main class of our application since JPackage will generate a new executable for our package&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;runtimeImage&lt;/em&gt; is usually set to our development OpenJDK, because JPackge could work with JLink to create the custom JRE, but because of some issues I found with JavaFX and JLink (the process is not straightforward), we trick JPackage and we tell it to take the previous custom JRE created with the OpenJFX plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Linux part&lt;/strong&gt; (I put it just for the sake of completeness)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;linuxShortcut&lt;/em&gt; creates a shortcut after the application installation process&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;linuxPackageName&lt;/em&gt; sets the final &lt;code&gt;deb&lt;/code&gt; package name&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;linuxAppCategory&lt;/em&gt; sets the Linux application category&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;linuxMenuGroup&lt;/em&gt; sets the Linux menu-group&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe I have to spend more words on the &lt;em&gt;tricky part&lt;/em&gt;. As mentioned above, JPackage is a tool for packaging a self-contained Java application, &lt;strong&gt;any&lt;/strong&gt; kind of Java application, modularized and non-modularized applications. But for this example, we want to distribute a simple animation and it would be quite weird to distribute a whole JRE image for the sake of one animation. Therefore, always think about what you really need for &lt;em&gt;your&lt;/em&gt; application and let the right tool works for you.&lt;/p&gt;

&lt;p&gt;About &lt;em&gt;linux part&lt;/em&gt;. JPackage allows you to package not only for Linux, but also for Windows and MacOS. However, JPackage depends on the operating system in order to work, so you can't package a Linux app, if you're using Window or MacOS, in a nutshell, no, cross-compiling is not an option. We will try to package our TreeFX app for Windows in an addendum to this article (maybe next week).&lt;/p&gt;

&lt;p&gt;Enough chatting. Let's see it work:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;mvn clean compile javafx:jlink jpackage:jpackage


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

&lt;/div&gt;

&lt;p&gt;Wait a while and then:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls &lt;/span&gt;target/dist/
treefx_1.0.0-1_amd64.deb


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

&lt;/div&gt;

&lt;p&gt;Nice fourice! We now have our package for AMD64 arch (yeah that's mine). If we still have some curiosity about how the &lt;code&gt;deb&lt;/code&gt; package is organized, we can unpack it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

 &lt;span class="nv"&gt;$ &lt;/span&gt;dpkg-deb &lt;span class="nt"&gt;-R&lt;/span&gt; target/dist/treefx_1.0.0-1_amd64.deb target/unpacked
 &lt;span class="nv"&gt;$ &lt;/span&gt;tree target/unpacked


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

target/unpacked
├── DEBIAN
│   ├── control
│   ├── postinst
│   ├── postrm
│   ├── preinst
│   └── prerm
└── opt
    └── treefx
        ├── bin
        │   └── TreeFX
        ├── lib
        │   ├── app
        │   │   └── TreeFX.cfg
        │   ├── runtime
        │   │   ├── [...]
        │   ├── TreeFX.png
        │   └── treefx-TreeFX.desktop
        └── share
            └── doc
                └── copyright


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

&lt;/div&gt;

&lt;p&gt;We could optimize things and surf into other JPackage configurations, but so far so good (as an old Bryan Adams' album and song said).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;We finally reached the bottom of this tutorial, a lot more could be said about JPMS, JLink and JPackage, this is indeed an introduction to tickle your curiosity, and as you can see we can still build nice stuff with JavaFX and Java technology.&lt;/p&gt;

&lt;p&gt;Dig into &lt;a href="https://gitlab.com/lucaguada/treefx" rel="noopener noreferrer"&gt;https://gitlab.com/lucaguada/treefx&lt;/a&gt; repository and look at the different branches to have a clearer vision of the above steps.&lt;/p&gt;

&lt;p&gt;See you, space cowboy!&lt;/p&gt;

&lt;p&gt;«A chance to begin again in a golden land of opportunity and adventure!»&lt;/p&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>jlink</category>
      <category>jpackage</category>
    </item>
    <item>
      <title>CQRS and Event Sourcing</title>
      <dc:creator>atipiJ</dc:creator>
      <pubDate>Mon, 21 Dec 2020 12:57:00 +0000</pubDate>
      <link>https://dev.to/cherrychain/cqrs-and-event-sourcing-398n</link>
      <guid>https://dev.to/cherrychain/cqrs-and-event-sourcing-398n</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;The purpose of this article is to go through some basic concepts of Command Query Responsibility Segregation (CQRS) and Event Sourcing design patterns.&lt;br&gt;
There's going to be an analysis of these patterns and then we will implement these to the use case.&lt;br&gt;
We will apply CQRS to the use case and we will apply Event Sourcing to fix some shortcomings of CQRS.&lt;/p&gt;

&lt;p&gt;Repository containing the Kata that we solved to implement the patterns: &lt;a href="https://gitlab.com/cherry-chain/bank-account-kata" rel="noopener noreferrer"&gt;CherryChain bank account kata&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  CQRS
&lt;/h1&gt;

&lt;p&gt;CQRS is a pattern used for modeling the domain of software. Its name stands for Command Query Responsibility Segregation and, as you can guess, its goal is to separate the writing part of the data from the reading part.&lt;br&gt;
Often in projects, these two concepts are enclosed in a single domain model. &lt;br&gt;
However, as the application begins to grow, it could easily become difficult to manage and expensive to maintain.&lt;br&gt;
On the contrary, by separating these two concepts of commands and queries, it is possible to maintain a low complexity even in very large projects.&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%2Fi%2Fevdcbx6hc1hobfu0rt9p.jpg" 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%2Fi%2Fevdcbx6hc1hobfu0rt9p.jpg" alt="cqrs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Event Sourcing
&lt;/h1&gt;

&lt;p&gt;Event Sourcing is an event-centric technique for persisting the &lt;strong&gt;Application State&lt;/strong&gt;. In this approach, the state is stored as a series of events, in an event store. When the state is updated, events are emitted and get inserted into the event store.&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%2Fi%2F4h0rph03o2wtrsi6n8g3.jpg" 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%2Fi%2F4h0rph03o2wtrsi6n8g3.jpg" alt="event_sourcing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Loading the state consists of iterating through all the saved events and summing them to reconstruct the state in its entirety. Whenever the state gets modified, an event is emitted. This means that any consumer that is listening to these events can handle them accordingly, using the data inside the event. A consumer is responsible for listening and consuming events.&lt;/p&gt;

&lt;p&gt;Event Sourcing has some inherent benefits when used as an application architecture, for example, it makes write operations much faster since it only has to generate and save a lightweight event.&lt;/p&gt;

&lt;p&gt;Using Event Sourcing alongside CQRS brings some advantages. In CQRS there is an application write repository which normally saves as-is when commands arrive. By substituting this part of the application with Event Sourcing, writing operations will become faster, and it will also be possible to have application state snapshots at any point in time.&lt;/p&gt;
&lt;h1&gt;
  
  
  Use case
&lt;/h1&gt;

&lt;p&gt;The scenario in which we're going to apply these patterns is the &lt;a href="https://github.com/dpanza/bank-kata-event-sourcing-cqrs" rel="noopener noreferrer"&gt;Bank account kata&lt;/a&gt; using the Kotlin programming language.&lt;br&gt;
The goal is to create a service that allows basic "banking" operations such as deposit and withdrawal. Of course everything&lt;br&gt;
has to be programmed following the patterns accordingly.&lt;/p&gt;

&lt;p&gt;Here is a list of features that we are going to develop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The bank can register a customer&lt;/li&gt;
&lt;li&gt;The bank can create an account for a customer&lt;/li&gt;
&lt;li&gt;The bank can deposit money to an account&lt;/li&gt;
&lt;li&gt;The bank can withdraw money from an account&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The bank can register a customer
&lt;/h2&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%2Fi%2Fnwrlage0e8v7dghiv3zs.jpg" 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%2Fi%2Fnwrlage0e8v7dghiv3zs.jpg" alt="register_customer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first step was to create a class representing the bank and allowing it to register a customer.&lt;br&gt;
Following the TDD (Test Driven Development) methodology we started by creating the following test and then proceeding with the implementation of the feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  @Test
  internal fun `it should register a customer`() {
    val customerId = bank.registerCustomer("Firstname Lastname")

    assertThat(bank.getCustomer(customerId).fullName).isEqualTo("Firstname Lastname")
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what we need is a function to register a customer and another one to read a customer, given his identifier.&lt;br&gt;
From now we can already begin to think about the CQRS pattern, which allows us to keep the concepts of writing and reading data isolated.&lt;br&gt;
When we want to register a customer we will have to launch a command, while when we want to read a customer we will have to make a query.&lt;/p&gt;

&lt;p&gt;At the moment we can focus on the registration function, in which the customer's full name is passed as input. The function then will generate an id (the id will be then returned by the function) and launch a command to create the new user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fun registerCustomer(fullName: String): UUID {
    val id = UUID.randomUUID()
    commandBus.publish(RegisterCustomer(id, fullName))
    return id
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our kata, to implement the registration of a new customer, we created the &lt;strong&gt;RegisterCustomer&lt;/strong&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sealed class Command

data class RegisterCustomer(val id: UUID, val fullName: String): Command()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the &lt;strong&gt;DefaultCommandBus&lt;/strong&gt; communication channel which is used to publish the commands that reach a class (which extends the &lt;strong&gt;CommandHandler&lt;/strong&gt; interface) that knows how to handle them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface CommandBus {
  fun publish(command: Command)
}

class DefaultCommandBus(private val handler: CommandHandler) : CommandBus {
  override fun publish(command: Command) {
    handler.handle(command)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have called the class used to manage these commands &lt;strong&gt;DefaultCommandHandler&lt;/strong&gt;, which, upon receiving &lt;strong&gt;RegisterCustomer&lt;/strong&gt; command, creates a new customer, registers it, and then saves it in the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface CommandHandler {
  fun handle(command: Command)
}

class DefaultCommandHandler(private val customerRepository: Repository&amp;lt;Customer&amp;gt;) : CommandHandler {
  override fun handle(command: Command) {
    when (command) {
      is RegisterCustomer -&amp;gt; registerCustomer(command)
    }
  }

  private fun registerCustomer(command: RegisterCustomer) {
    val customer = Customer()
    customer.register(command.id, command.fullName)
    customerRepository.put(customer)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Customer&lt;/strong&gt; state contains information regarding the bank's customer. There are an identification code and full name. Since we have used the Event Sourcing pattern to make sure our client's story is not lost, we don't update the information directly. We save it as a list of events. As we can see, the function used for registration adds the &lt;strong&gt;CustomerRegistered&lt;/strong&gt; event&lt;br&gt;
to the customer state's &lt;strong&gt;changes&lt;/strong&gt; list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Customer {
  lateinit var id: UUID
  val changes = mutableListOf&amp;lt;Event&amp;gt;()

  fun register(id: UUID, fullName: String) {
    changes.add(CustomerRegistered(id, fullName))
  }
}

interface Event { val id: UUID }

data class CustomerRegistered(override val id: UUID, val fullName: String) : Event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Repository&lt;/strong&gt; where our new customer is stored is made up of an &lt;strong&gt;EventStore&lt;/strong&gt; and an &lt;strong&gt;EventBus&lt;/strong&gt;. When the function to save the customer is called, each of the events regarding that particular customer (identified by an id) are saved in the Store and then sent via the dedicated Bus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Repository&amp;lt;T&amp;gt; {
  fun put(entity: T)
}

class InMemoryCustomerRepository(private val eventStore: EventStore, private val eventBus: EventBus): Repository&amp;lt;Customer&amp;gt; {
  override fun put(customer: Customer) {
    customer.changes.forEach {
      eventStore.append(it)
      eventBus.emit(it)
    }
  }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;InMemoryEventStore&lt;/strong&gt; is our class that takes care of keeping events in memory and then being subsequently interrogated when necessary. (It doesn't necessarily need to be an in-memory implementation, the &lt;strong&gt;EventStore&lt;/strong&gt; interface can be implemented as any one wishes).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface EventStore {
  fun append(event: Event)
}

class InMemoryEventStore : EventStore {
  private val list = mutableListOf&amp;lt;Event&amp;gt;()

  override fun append(event: Event) {
    list.add(event)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DefaultEventBus&lt;/strong&gt; is the communication channel where all the events are sent which are then managed by the &lt;strong&gt;EventHandler&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface EventBus {
  fun emit(event: Event)
}

class DefaultEventBus(private vararg val handlers: EventHandler) : EventBus {
  override fun emit(event: Event) {
      handlers.forEach { it.handle(event) }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CustomerViewsEventHandler&lt;/strong&gt; is a class that handles customer events and is has a collaborator called &lt;strong&gt;CustomerViews&lt;/strong&gt;. When this handler receives a &lt;strong&gt;CustomerRegistered&lt;/strong&gt; event, it creates a &lt;strong&gt;CustomerView&lt;/strong&gt; with the data it receives and projects it in the view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface EventHandler {
  fun handle(event: Event)
}

class CustomerViewsEventHandler(private val customerViews: CustomerViews) : EventHandler {
  override fun handle(event: Event) {
    when(event) {
      is CustomerRegistered -&amp;gt; handle(event)
    }
  }

  fun handle(event: CustomerRegistered) {
    customerViews.add(CustomerView(event.id, event.fullName))
  }
}

data class CustomerView(val id: UUID, val fullName: String)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;InMemoryCustomerViews&lt;/strong&gt; is the view where all customer information is projected into. The views can then be queried by the bank using the get function. This keeps the command and query logic separate as indicated by the CQRS pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface CustomerViews {
  fun add(customerView: CustomerView)
  fun get(customerId: UUID): CustomerView
}

class InMemoryCustomerViews: CustomerViews {
  private val data = mutableMapOf&amp;lt;UUID, CustomerView&amp;gt;()

  override fun add(customerView: CustomerView) {
    data[customerView.id] = customerView
  }

  override fun get(customerId: UUID): CustomerView {
    return data[customerId]!!
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, the first point of the kata was completed following the CQRS and Event Sourcing pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bank can create an account for a customer
&lt;/h2&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%2Fi%2Fzm6epyiyav3chc2p0q28.jpg" 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%2Fi%2Fzm6epyiyav3chc2p0q28.jpg" alt="create_account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we want to make sure that the bank can create one or more accounts for each customer where the balance will be stored.&lt;br&gt;
After creating the test we went on to write a function to create an account on a specific customer, in which an id is generated to identify the account and then publish the &lt;strong&gt;CreateAccount&lt;/strong&gt; command on the command bus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fun createAccount(customerId: UUID): UUID {
    val id = UUID.randomUUID()
    commandBus.publish(CreateAccount(id, customerId));
    return id;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we saw in the previous chapter, the class that will handle the command we published is &lt;strong&gt;DefaultCommandHandler&lt;/strong&gt;.&lt;br&gt;
So in addition to the management of the "RegisterCustomer" command, we have added the management of the new CreateAccount command.&lt;br&gt;
A new account is created with the id and customer id passed by the command and finally stored in the repository in the same way we saw in the previous chapter (using EventStore and EventBus).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DefaultCommandHandler(private val accountRepository: Repository&amp;lt;Account&amp;gt;, private val customerRepository: Repository&amp;lt;Customer&amp;gt;) : CommandHandler {

  override fun handle(command: Command) {
    when (command) {
      is RegisterCustomer -&amp;gt; registerCustomer(command)
      is CreateAccount -&amp;gt; create(command)
    }
  }

  private fun registerCustomer(command: RegisterCustomer) {
    val customer = Customer()
    customer.register(command.id, command.fullName, command.type)
    customerRepository.put(customer)
  }

  private fun create(createAccount: CreateAccount) {
    val currentAccount = Account()
    currentAccount.create(createAccount.id, createAccount.customerId)
    accountRepository.put(currentAccount)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Account&lt;/strong&gt; class is composed as follows: an identifier, a customer id, and a list of events.&lt;br&gt;
When the creation method is used, the &lt;strong&gt;AccountCreated&lt;/strong&gt; event is produced which will then be published by the &lt;strong&gt;Repository&lt;/strong&gt; on the event bus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Account() {
  lateinit var id: UUID
  lateinit var customerId: UUID
  val change = mutableListOf&amp;lt;Event&amp;gt;()

  fun create(id: UUID, customerId: UUID) {
    change.add(AccountCreated(id, customerId))
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the &lt;strong&gt;AccountViewsEventHandler&lt;/strong&gt; class will receive the &lt;strong&gt;AccountCreated&lt;/strong&gt; event with which the &lt;strong&gt;AccountViews&lt;/strong&gt; projection will be populated. It will then be possible to make queries to find out the balance of each customer.&lt;br&gt;
As you can see from the code, in the phase of creating the balance it is initialized to zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AccountViewsEventHandler(private val accountViews: AccountViews) : EventHandler {
  override fun handle(event: Event) {
    when (event) {
      is AccountCreated -&amp;gt; handle(event)
    }
  }

  private fun handle(accountCreated: AccountCreated) {
    accountViews.insert(AccountView(
      id = accountCreated.id,
      customerId = accountCreated.customerId,
      balance = 0
    ))
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also in this new feature that we added to the bank, we were able to follow the CQRS and ES pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bank can deposit money to an account
&lt;/h2&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%2Fi%2F3i5ua5mur8bxej6qp115.jpg" 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%2Fi%2F3i5ua5mur8bxej6qp115.jpg" alt="deposit_money"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To allow the bank to deposit money to an account, we allowed our application to handle the &lt;strong&gt;DepositMoney&lt;/strong&gt; command. The handler of this command will update the &lt;strong&gt;Account&lt;/strong&gt; state by increasing its balance based on the amount deposited. Before doing this update operation, it first has to load the existing account information. This is the function (present in the &lt;strong&gt;DefaultCommandHandler&lt;/strong&gt;) that handles the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private fun deposit(depositMoney: DepositMoney) {
    val currentAccount = accountRepository.get(id = depositMoney.accountId)

    if (currentAccount!=null) {
      currentAccount.deposit(depositMoney.amount)
      accountRepository.put(currentAccount)
    } else {
      throw BankException("account does not exist")
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We know that this information is stored as a series of events in our event store. So before doing any update operation, the application first reads all the events, saved in the event store, relative to the specific account in which the money will be deposited.&lt;br&gt;
We then create an empty instance of  &lt;strong&gt;Account&lt;/strong&gt;. These events are then used in the &lt;strong&gt;hydrate&lt;/strong&gt; function present in the empty &lt;strong&gt;Account&lt;/strong&gt; instance, which iterates through the events and creates the state information from scratch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class InMemoryAccountRepository(private val eventStore: EventStore, private val eventBus: EventBus) : Repository&amp;lt;Account&amp;gt; {
  override fun get(id: UUID): Account? {
    val events = eventStore.getEventsBy(id = id)
    return if (events.isEmpty()) {
      null
    } else {
      val account = Account()
      account.hydrate(events)
      account
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;hydrate()&lt;/strong&gt; function works as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fun hydrate(events: List&amp;lt;Event&amp;gt;) {
    events.forEach {event -&amp;gt;
      when (event) {
        is AccountCreated -&amp;gt; {
          this.id = event.id
          this.customerId = event.customerId
        }
        is MoneyDeposited -&amp;gt; this.balance += event.amount
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a key step in &lt;strong&gt;Event Sourcing&lt;/strong&gt;. As we can see, all the events are processed and based on their type, an update operation is applied to the &lt;strong&gt;Account&lt;/strong&gt; instance. This means that the first event must be an &lt;strong&gt;AccountCreated&lt;/strong&gt; event, which will set the account's &lt;strong&gt;id&lt;/strong&gt; and &lt;strong&gt;customerId&lt;/strong&gt;. Every other &lt;strong&gt;MoneyDeposited&lt;/strong&gt; event that might have been emitted in the past will be iterated through, and will update the current &lt;strong&gt;Account&lt;/strong&gt; instance. After the hydration is done, we will have in our hands the instance of the account that had been stored as a series of events in the event store. We update the &lt;strong&gt;changes&lt;/strong&gt; of this instance by putting in our new &lt;strong&gt;MoneyDeposited&lt;/strong&gt; event, which is then emitted to the event bus and appended to the event store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class InMemoryAccountRepository(private val eventStore: EventStore, private val eventBus: EventBus) : Repository&amp;lt;Account&amp;gt; {
  override fun put(account: Account) {
    account.change.forEach { event -&amp;gt;
      eventStore.append(event)
      eventBus.emit(event)
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is intercepted by the &lt;strong&gt;AccountViewsEventHandler&lt;/strong&gt;. This handler is responsible for keeping the &lt;strong&gt;Account Views&lt;/strong&gt; synchronized with the actual state. The &lt;strong&gt;Views&lt;/strong&gt; are the part of the application that are visible externally. The views don't necessarily store the state as-is the state can receive any desired transformation before being exposed externally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AccountViewsEventHandler(private val accountViews: AccountViews) : EventHandler {
  private fun handle(moneyDeposited: MoneyDeposited) {
    val accountView = accountViews.get(moneyDeposited.id)
    val updatedView = accountView.copy(balance = accountView.balance + moneyDeposited.amount)
    accountViews.delete(moneyDeposited.id)
    accountViews.insert(updatedView)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this feature, it is possible to deposit money into an account. We also encountered the &lt;strong&gt;hydrate()&lt;/strong&gt; function, which helps us to update an existing account by iterating through the events present in the event store.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bank can withdraw money from an account
&lt;/h2&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%2Fi%2Fnxbhisezfl073t1oqjlg.jpg" 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%2Fi%2Fnxbhisezfl073t1oqjlg.jpg" alt="withdraw_money"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To allow the bank to withdraw money from an account, the application handles the &lt;strong&gt;WithdrawMoney&lt;/strong&gt; command. This operation is analogous to the depositing of money. This function is present in the &lt;strong&gt;DefaultCommandHandler&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private fun withdraw(withdrawMoney: WithdrawMoney) {
  val currentAccount = accountRepository.get(id = withdrawMoney.accountId)

  if (currentAccount.hasEnough(withdrawMoney.amount)) {
    currentAccount.withdraw(withdrawMoney.amount)
    accountRepository.put(currentAccount)
  } else {
    throw BankException("not enough money")
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It updates the &lt;strong&gt;Account&lt;/strong&gt; by decreasing its balance based on the amount withdrawn. The withdraw process first loads the state information by iterating through its stored events (&lt;strong&gt;hydrate()&lt;/strong&gt; function):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun hydrate(events: List&amp;lt;Event&amp;gt;) {
  events.forEach {event -&amp;gt;
    when (event) {
      is AccountCreated -&amp;gt; {
        this.id = event.id
        this.customerId = event.customerId
      }
      is MoneyDeposited -&amp;gt; this.balance += event.amount
      is MoneyWithdrawn -&amp;gt; this.balance -= event.amount
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the events have been iterated through completely, then we have the &lt;strong&gt;Account&lt;/strong&gt; instance that we wanted and we can proceed with updating it. At this point a &lt;strong&gt;MoneyWithdrawn&lt;/strong&gt; event is created, containing the necessary information of the withdrawal it is then appended to the &lt;strong&gt;changes&lt;/strong&gt; of the account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun withdraw(amount: Int, fee: Int) {
  change.add(MoneyWithdrawn(id, amount, fee))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This event is then saved to the event store, emitted to the event bus and intercepted by the &lt;strong&gt;AccountViewsEventHandler&lt;/strong&gt;, which projects the changes to the &lt;strong&gt;AccountViews&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private fun handle(moneyWithdrawn: MoneyWithdrawn) {
  val accountView = accountViews.get(moneyWithdrawn.id)
  val updatedView = accountView.copy(balance = accountView.balance - moneyWithdrawn.amount)
  accountViews.delete(moneyWithdrawn.id)
  accountViews.insert(updatedView)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this feature, it is possible to withdraw money from an account.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;As we have seen, by using the CQRS and ES pattern, we managed to solve this kata. &lt;br&gt;
Some pros of this pattern are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is a single source of truth&lt;/li&gt;
&lt;li&gt;Views can be generated with high customization&lt;/li&gt;
&lt;li&gt;The separation of actions that change the state and queries can bring high optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However there are some obstacles (or &lt;em&gt;opportunities!&lt;/em&gt;) that need to be conquered when working with this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kickstarting a project can prove difficult&lt;/li&gt;
&lt;li&gt;There is a necessity to have a good model of the domain of the project&lt;/li&gt;
&lt;li&gt;Events might lose meaning over time if the domain isn't modeled properly&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kotlin</category>
      <category>eventsourcing</category>
      <category>cqrs</category>
      <category>kata</category>
    </item>
    <item>
      <title>Zero Downtime Deployment with Docker Swarm</title>
      <dc:creator>ndr_brt</dc:creator>
      <pubDate>Mon, 21 Dec 2020 12:54:27 +0000</pubDate>
      <link>https://dev.to/cherrychain/zero-downtime-deployment-with-docker-swarm-25n2</link>
      <guid>https://dev.to/cherrychain/zero-downtime-deployment-with-docker-swarm-25n2</guid>
      <description>&lt;p&gt;If you are a software developer that in the past has dealt with production software, you are certainly familiar with this struggle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;deployment time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you have already put into effect measures to &lt;strong&gt;trust your deployment&lt;/strong&gt; by taking advantage of great practices such as Continuous Integration, Automated Testing, Continuous Delivery and so on, these should be carried out before tackling the thing I’m going to talk about. This is &lt;strong&gt;not&lt;/strong&gt; going to be a silver bullet.&lt;/p&gt;

&lt;p&gt;Today we’ll talk about &lt;strong&gt;zero downtime&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  the problem
&lt;/h2&gt;

&lt;p&gt;Imagine you have already packaged your application into a docker image, published it into a docker registry and have it up and running in production by the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run …
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing wrong, your application is good to go.&lt;/p&gt;

&lt;p&gt;But… how can we update it?&lt;/p&gt;

&lt;p&gt;The easiest solution is to stop the old one and start the new version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop &amp;lt;running container &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

docker run &amp;lt;new version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s a problem with this approach: from the time you stop the old container and the complete bootstrap of the new version, your application will not respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  the solution
&lt;/h2&gt;

&lt;p&gt;This problem is pretty common and can be solved in many ways. We discovered an almost “effort free” way using &lt;strong&gt;Docker Swarm&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what is Docker Swarm?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Swarm is a Docker “mode” already included in your Docker installation. It’s a powerful cluster engine that will help you scale your application.&lt;/p&gt;

&lt;p&gt;Also, it will solve your downtime problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;how?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The idea is to transform your docker instance into a single node swarm cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker swarm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command should return something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Swarm initialized: current node &lt;span class="o"&gt;(&lt;/span&gt;&amp;lt;node_id&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt; is now a manager.

To add a worker to this swarm, run the following &lt;span class="nb"&gt;command&lt;/span&gt;:

docker swarm &lt;span class="nb"&gt;join&lt;/span&gt; — token &amp;lt;swarm_token&amp;gt; &amp;lt;node_addess+port&amp;gt;

To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are instructions for adding nodes to our cluster. But you don’t need that now.&lt;/p&gt;

&lt;p&gt;Now you need to deploy the &lt;strong&gt;stack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In order to achieve that, you need to define a &lt;strong&gt;docker-compose&lt;/strong&gt; file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;‘3.7’&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${IMAGE}&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-server&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;‘8080:8080’&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-network&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;“CMD”&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;“curl”&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;“-i”&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8080/health"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replicated&lt;/span&gt;
      &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
      &lt;span class="na"&gt;update_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;start-first&lt;/span&gt;
        &lt;span class="na"&gt;failure_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rollback&lt;/span&gt;
        &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example there is just one container, but you can deploy as many as you need.&lt;/p&gt;

&lt;p&gt;Some concepts:&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;image&lt;/strong&gt;: a variable that represents the image name and version&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;network&lt;/strong&gt;: the stack network, with this various services can communicate with each other&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;healthcheck&lt;/strong&gt;: definitions of commands that verify the service status (up or down). The commands should return &lt;code&gt;error code = 0&lt;/code&gt; when the service status is good and &lt;code&gt;error code != 0&lt;/code&gt; when the service has not started yet, stopped, paused, etc..&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;replicas&lt;/strong&gt;: the numbers of parallel containers of the service that will be deployed&lt;/p&gt;

&lt;p&gt;You can start your service by the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;IMAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IMAGE_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IMAGE_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

docker stack deploy &lt;span class="nt"&gt;-c&lt;/span&gt; docker-compose.yml &amp;lt;stack_name&amp;gt; — with-registry-auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you are ready to update your service, you can use the same command, with a different value of &lt;strong&gt;IMAGE_VERSION&lt;/strong&gt;, and there will be no downtime since Swarm will take care of starting the new containers and, once started correctly, it will also take care of stopping the old ones.&lt;/p&gt;

</description>
      <category>deploy</category>
      <category>docker</category>
      <category>swarm</category>
    </item>
    <item>
      <title>Throttle HTTP requests on paged resources with Vert.x</title>
      <dc:creator>ndr_brt</dc:creator>
      <pubDate>Mon, 21 Dec 2020 12:53:40 +0000</pubDate>
      <link>https://dev.to/cherrychain/throttle-http-requests-on-paged-resources-with-vert-x-5cjm</link>
      <guid>https://dev.to/cherrychain/throttle-http-requests-on-paged-resources-with-vert-x-5cjm</guid>
      <description>&lt;p&gt;Hey Java developers, I know that you are interested in asynchronous programming and I know you are struggling with such paradigm.&lt;br&gt;
I know that because I’m one of you!&lt;/p&gt;

&lt;p&gt;Let us see how to deal with rate limiting issues in the magical async world in Java with Vert.x.&lt;/p&gt;

&lt;p&gt;For the unaware a little recap:&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Vert.x?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vertx.io/" rel="noopener noreferrer"&gt;Vert.x&lt;/a&gt; is a polyglot event-driven and non-blocking application framework.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is “Rate limiting”?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Rate_limiting" rel="noopener noreferrer"&gt;Rate limiting&lt;/a&gt; is a set of policies implemented by a web server used to force client to “throttle” requests from being overloading.&lt;/p&gt;
&lt;h2&gt;
  
  
  What are paged resources?
&lt;/h2&gt;

&lt;p&gt;Paged resources are resources split in various pages to prevent overloading.&lt;/p&gt;

&lt;p&gt;We will work with a real implementation case:&lt;/p&gt;

&lt;p&gt;We are music fanatics (as I am), we are users of &lt;a href="https://www.discogs.com" rel="noopener noreferrer"&gt;Discogs.com&lt;/a&gt;, and we want to fetch its data in our &lt;strong&gt;non-blocking&lt;/strong&gt; application.&lt;/p&gt;

&lt;p&gt;Taking a look at the &lt;a href="https://www.discogs.com/developers" rel="noopener noreferrer"&gt;discogs.com API reference&lt;/a&gt; we will notice that — aside from the API specifications — there are some information about data format, headers, versioning and so on.&lt;br&gt;
We are now interested in two sections: &lt;strong&gt;Rate Limiting&lt;/strong&gt; and &lt;strong&gt;Pagination&lt;/strong&gt;.&lt;br&gt;
Those are the problems to deal with.&lt;/p&gt;

&lt;p&gt;A sketch of our architecture&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%2Fcdn-images-1.medium.com%2Fmax%2F7992%2F1%2AsAQQ_JJqYG8hHsNAYmygFA.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%2Fcdn-images-1.medium.com%2Fmax%2F7992%2F1%2AsAQQ_JJqYG8hHsNAYmygFA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every arrow from left to right is a method call, every arrow from right to left is a Future.&lt;/p&gt;

&lt;p&gt;We will start from the bottom and go up the river.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rate Limiting
&lt;/h2&gt;

&lt;p&gt;Discogs permits, according with documentation, 25 request per minute, so, 25 will be our rate limit, and one minute is the size of the rate limit window.&lt;/p&gt;

&lt;p&gt;The idea is to have an interface with a method called *execute *which will accept a Request (a data object that represents the request) as parameter and return a Future (because we think async!) of Buffer, that is the response’s body. &lt;br&gt;
Trivial and neat.&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="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Requests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;**(&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&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;We need to put a delay between requests, hence inside the &lt;em&gt;RequestExecutor&lt;/em&gt; implementation we will use a queue to decouple the &lt;em&gt;execute&lt;/em&gt; invocations from the throttled request 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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThrottledRequests&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Requests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RequestContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;        
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&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;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;failedFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&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;em&gt;RequestContext&lt;/em&gt; is a simple data object that allow us to bind request to its future.&lt;/p&gt;

&lt;p&gt;Then, the request should be consumed from the queue and executed, we will do this with a periodic task by starting it every N milliseconds, where N is a non-fixed value computed from the maximum number of requests we are allowed to do in the rate limit window.&lt;/p&gt;

&lt;p&gt;At first we will start with an optimistic &lt;em&gt;1&lt;/em&gt;, therefore here’s our &lt;em&gt;ThrottledRequests&lt;/em&gt; constructor:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThrottledRequests&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Requests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;RATE_LIMIT_WINDOW_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BlockingQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RequestContext&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedBlockingQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;AtomicLong&lt;/span&gt; &lt;span class="n"&gt;executorId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AtomicLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;AtomicLong&lt;/span&gt; &lt;span class="n"&gt;actualDelay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AtomicLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Vertx&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;ThrottledRequests&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vertx&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;vertx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createHttpClient&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPeriodic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actualDelay&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="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executorId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&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;Some explanations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;vertx&lt;/em&gt;: you need the vertx instance to launch a periodic executor.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;actualDelay&lt;/em&gt;: is an AtomicLong that represent the actual delay, so, as we said before, it’s starting value is &lt;em&gt;1.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;executor()&lt;/em&gt;: core method of the class, it insantiate a function that will perform the throttled requests.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;executorId&lt;/em&gt;: we need to track the executor task id to stop it when the actualDelay will change. Is an AtomicLong too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let us see how to handle async request executions:&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;timerId&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;RequestContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;inputRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;inputRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User-Agent"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"YourApp/0.1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFollowRedirects&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bodyHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;checkAndUpdateRateLimit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;})&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&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;Easy, uh?&lt;br&gt;
On every request responded we complete the future and…checkAndUpdateRateLimit():&lt;br&gt;
according to the API documentation, there is a header in every response we will get from &lt;em&gt;discogs&lt;/em&gt; called &lt;strong&gt;X-Discogs-Ratelimit&lt;/strong&gt;, that tells us how many requests we can do in a rate limit window of 1 minute. Cool.&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="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;checkAndUpdateRateLimit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpClientResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Discogs-Ratelimit"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Long:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;parseLong&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rateLimit&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rateLimit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reqPerMinute&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;RATE_LIMIT_WINDOW_SIZE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;reqPerMinute&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ifPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;throttleDelay&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;throttleDelay&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;actualDelay&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAndSet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;throttleDelay&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancelTimer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executorId&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="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPeriodic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;throttleDelay&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;executorId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&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;The calculation is pretty simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the rate limit header&lt;/li&gt;
&lt;li&gt;Subtract one, just to avoid to fill the window&lt;/li&gt;
&lt;li&gt;Calculate the delay you should take between requests to do less than rateLimit requests in the time window (one minute)&lt;/li&gt;
&lt;li&gt;If the delay is different from the current one, we remove the old executor’s timer and define another one with a new delay time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pagination
&lt;/h2&gt;

&lt;p&gt;Handling pagination is a little trickier than rate limit, since there is some work to do with futures, you know, the total page count will be known only after fetching the first page.&lt;/p&gt;

&lt;p&gt;The idea is to divide responsibilities, we will implement three components:&lt;br&gt;
(the example is on the Inventory resource, which retrieves Listing entities)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GetListingPage: one implementation for every resource, such class uses Requests as collaborator, knows the url to invoke and knows how to deserialize the single fetched page. So its responsability is the Page.&lt;/li&gt;
&lt;li&gt;Pages uses GetResourcePage to fetch first page and eventually the others, join them. Its responsibility is the Pages.&lt;/li&gt;
&lt;li&gt;Client obtains all the pages from Pages and extract the entities from those.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start from GetListingPage, is a class that implement an interface with one method: apply&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="nd"&gt;@Override&lt;/span&gt;
&lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ListingPage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;pageNumber&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Request {} inventory page {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pageNumber&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;path&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="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/users/%s/inventory?page=%d"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pageNumber&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Request&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="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ListingPage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;setHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="nc"&gt;ListingPage&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ListingPage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cause&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;future&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;Nothing special, execute request and deserialize JSON output to ListingPage class (a class that represent the ListingPage structure).&lt;/p&gt;

&lt;p&gt;Maybe the more interesting class is Pages. The public method is getFor:&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&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="nf"&gt;getFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&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="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;*();&lt;/span&gt;

  &lt;span class="n"&gt;getPage&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="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;setHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Total pages: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalPages&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

      &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;futures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntStream&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalPages&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapToObj&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPage&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="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

      &lt;span class="nc"&gt;CompositeFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;futures&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joinPages&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&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;We will ask for the first page and then, knowing the total pages count, we’ll ask for every other page, combining all the Futures into a CompositeFuture.&lt;/p&gt;

&lt;p&gt;When every future will be completed, we will joinPages:&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AsyncResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CompositeFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;joinPages&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&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="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;CompositeFuture&lt;/span&gt; &lt;span class="n"&gt;remnants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="nc"&gt;Collection&lt;/span&gt; &lt;span class="n"&gt;remnantPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntStream&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remnants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapToObj&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;remnants:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;resultAt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

      &lt;span class="nc"&gt;List&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="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
      &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remnantPages&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cause&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&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;Now, at the higher level (Client) we can just get pages and extract entities:&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;listingPages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;setHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Listing&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;listings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;ListingPage:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;listings&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Collection:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="n"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;*()));&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;logic&lt;/span&gt; &lt;span class="o"&gt;...&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;Pretty cool, huh?&lt;/p&gt;

&lt;p&gt;Source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;a href="https://gist.github.com/andreabertagnolli/f2cfacadc5c7bd00f24284c86f81dc79" rel="noopener noreferrer"&gt;ThrottledRequests&lt;/a&gt;&lt;/em&gt;: &lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/andreabertagnolli/8983d0cd1dace16e426b81c72430f14e" rel="noopener noreferrer"&gt;GetListingPage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/andreabertagnolli/a7a5d2e2e1980a1554e0b50e0594c622" rel="noopener noreferrer"&gt;Pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/andreabertagnolli/a8398b8187cf02d94aef21b4c0e751cd" rel="noopener noreferrer"&gt;Client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vertx</category>
      <category>async</category>
      <category>java</category>
      <category>throttling</category>
    </item>
    <item>
      <title>TDD in an event driven application</title>
      <dc:creator>ndr_brt</dc:creator>
      <pubDate>Mon, 21 Dec 2020 12:52:53 +0000</pubDate>
      <link>https://dev.to/cherrychain/tdd-in-an-event-driven-application-2d6i</link>
      <guid>https://dev.to/cherrychain/tdd-in-an-event-driven-application-2d6i</guid>
      <description>&lt;p&gt;You (should) know, Test Driven Development is one of the greatest practice in software development: it gives you confidence in what you implement, it gives you courage to refactor or change behaviors, it forces you to think about what you are about to implement.&lt;/p&gt;

&lt;p&gt;For sure not every piece of code deserves to be written test-first, but at least you should start thinking: “Can I write a test before?”.&lt;/p&gt;

&lt;p&gt;Passing to an event driven world the process remains the same: &lt;br&gt;
there’s a &lt;a href="http://xunitpatterns.com/SUT.html" rel="noopener noreferrer"&gt;SUT&lt;/a&gt;, a trigger action, and some behavior verification:&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%2Fcdn-images-1.medium.com%2Fmax%2F7824%2F1%2ALbGaYOzMRXDYwOcWErK1eQ.jpeg" 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%2Fcdn-images-1.medium.com%2Fmax%2F7824%2F1%2ALbGaYOzMRXDYwOcWErK1eQ.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider implementing a feature for an hypothetical Continuous Integration application, on tests executed should check the results and notify to the application. This application in based on &lt;a href="https://vertx.io/" rel="noopener noreferrer"&gt;Vert.x framework&lt;/a&gt; and is coded in &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin language&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So our first test will be: “&lt;em&gt;on tests executed, when they passed, should emit tests passed”:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ExtendWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VertxExtension&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckTestsExecutionTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Test&lt;/span&gt;
  &lt;span class="nd"&gt;@Timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeUnit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SECONDS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`on&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="n"&gt;executed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="nf"&gt;passed`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Vertx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;VertxTestContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;CheckTestsExecution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsPassed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;completeNow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsExecuted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;TestsExecuted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nc"&gt;TestResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"simple test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s a lot of stuff in there. The &lt;em&gt;VertxExtension *class&lt;/em&gt; &lt;em&gt;is a junit5 extension provided by the library *vertx-junit5&lt;/em&gt; that gives some facilities to write Vert.x unit tests.&lt;/p&gt;

&lt;p&gt;But, the very important thing here is that there’s &lt;strong&gt;no assertion&lt;/strong&gt;. The reason is simple: we are testing an &lt;strong&gt;asynchronous behavior&lt;/strong&gt;, so we will get no synchronous output from our .&lt;/p&gt;

&lt;p&gt;What we need here is to set an &lt;strong&gt;expectation&lt;/strong&gt;. To do that we create a consumer on the event we expecting to be launched from our SUT. To make test pass then we call the &lt;em&gt;completeNow&lt;/em&gt; method on &lt;em&gt;context&lt;/em&gt; object (is a Vert.x junit5 extension utility to handle asynchronous tests, as well as &lt;em&gt;@Timeout&lt;/em&gt; annotation).&lt;br&gt;
The test will pass only when &lt;em&gt;completeNow&lt;/em&gt; method is called before the timeout. Simple.&lt;/p&gt;

&lt;p&gt;The last test row emits an event that should trigger our desired behavior.&lt;br&gt;
Obviously, after fixing compilation errors, the test will &lt;strong&gt;fail&lt;/strong&gt;. Red bar, cool.&lt;/p&gt;

&lt;p&gt;Let’s write &lt;strong&gt;only enough code&lt;/strong&gt; to make test pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckTestsExecution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsExecuted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsPassed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Green bar. Go on.&lt;/p&gt;

&lt;p&gt;Now, we need to describe the case where one test fails and so we will expect to receive &lt;em&gt;TestsFailed&lt;/em&gt; event. We should also expect not to receive &lt;em&gt;TestsPasses&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;  &lt;span class="nd"&gt;@Test&lt;/span&gt;
  &lt;span class="nd"&gt;@Timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeUnit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SECONDS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`on&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="n"&gt;executed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="nf"&gt;passed`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Vertx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;VertxTestContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;CheckTestsExecution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsPassed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;failNow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No TestPassed event should be emitted"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsFailed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;completeNow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;testResults&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nc"&gt;TestResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"simple test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsExecuted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TestsExecuted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testResults&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Red bar again, so, make it green ASAP!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckTestsExecution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsExecuted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;testExecuted&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mapTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TestsExecuted&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testExecuted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;passed&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsPassed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TestsFailed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect, you just implemented an event driven component with TDD on Vert.x in Kotlin. Refactoring is up to you.&lt;/p&gt;

&lt;p&gt;As you see, no great difference from the classic TDD approach: think, write a test, do something and expect behaviors, just pay attention to asynchronous manners and use expectations.&lt;/p&gt;

</description>
      <category>eventdriven</category>
      <category>async</category>
      <category>tdd</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Handle backpressure between Kafka and a database with Vert.x

</title>
      <dc:creator>ndr_brt</dc:creator>
      <pubDate>Thu, 06 Aug 2020 06:52:39 +0000</pubDate>
      <link>https://dev.to/cherrychain/handle-backpressure-between-kafka-and-a-database-with-vert-x-5a3j</link>
      <guid>https://dev.to/cherrychain/handle-backpressure-between-kafka-and-a-database-with-vert-x-5a3j</guid>
      <description>&lt;p&gt;As we &lt;a href="https://dev.to/cherrychain/introduction-to-vert-x-37nb"&gt;already discussed in the past&lt;/a&gt;, asynchronous programming brings many pros in developing reactive and responsive applications. However, it also carries cons and challenges, one of the main ones is the backpressure problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is backpressure?
&lt;/h4&gt;

&lt;p&gt;In physics&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it is a resistance or force opposing the desired flow of fluid through pipes (&lt;a href="https://en.wikipedia.org/wiki/Back_pressure" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can translate the problem on a known scenario: persistence of messages polled from a bus, where there are a huge amount of messages on a bus that our application is polling really fast, but the database underneath is really slow.&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%2Fi%2F7cdnoazuit8m9ab2za9e.jpg" 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%2Fi%2F7cdnoazuit8m9ab2za9e.jpg" alt="real world example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How can be funnel overflow be avoided?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a synchronous scenario, there's no backpressure's issue, the sync nature of the computation blocks the polling from the bus until the current message is processed.&lt;br&gt;
But, in the async world, the polling is executed without clues on what's happening on the database. So if the database can't handle all the messages coming from the bus, the messages will remain "in between", which means in the memory of our service. &lt;br&gt;
This can lead to failures or, at worst, to service fault.&lt;/p&gt;

&lt;p&gt;Let's try to develop an application that persists messages in a database, and make it evolve to handle backpressure&lt;/p&gt;

&lt;h4&gt;
  
  
  Automatic polling
&lt;/h4&gt;

&lt;p&gt;At first, our verticle will do those operations: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;initialize the JDBC client&lt;/li&gt;
&lt;li&gt;initialize the Kafka client&lt;/li&gt;
&lt;li&gt;subscribe to the topic&lt;/li&gt;
&lt;li&gt;persist the records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code is quite simple, and it works well with small amounts of messages. &lt;br&gt;
When the load gets bigger and bigger a problem appears: using the handler of Vertx Kafka consumer means that there's no control on the message ratio, so it will poll continuously without considering the persistance rate, causing memory overload.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainVerticle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractVerticle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JDBCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datasourceConfiguration&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;KafkaConsumer&lt;/span&gt;&lt;br&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;,&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="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;&lt;br&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"topic.name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
        &lt;span class="n"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;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;"Message persisted"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;br&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;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;err&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;"Message not persisted "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cause&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;&lt;br&gt;
      &lt;span class="o"&gt;});&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;BOOTSTRAP_SERVERS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"kafkahost:9092"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;KEY_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;VALUE_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UpdateResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumerRecord&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;,&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="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UpdateResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;JsonArray&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toParams&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateWithParams&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"insert or update query to persist record"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="nf"&gt;datasourceConfiguration&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="c1"&gt;// TODO datasource configuration&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;JsonArray&lt;/span&gt; &lt;span class="nf"&gt;toParams&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;KafkaConsumerRecord&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;,&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="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="c1"&gt;// TODO: convert the record into params for the sql command&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h4&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Explicit polling&lt;br&gt;
&lt;/h4&gt;

&lt;p&gt;To handle the backpressure, explicit polling shall be used, and this can be done by avoiding the kafka consumer's handler setting and by calling &lt;code&gt;poll&lt;/code&gt; manually (in the following case, every 100ms).&lt;br&gt;
By using this approach, it can be made so that every poll gets performed only when the batch of previously polled messages are persisted.&lt;br&gt;
This behaviour can be achieved by handling every message's &lt;code&gt;persist&lt;/code&gt; future and collecting all of them with the &lt;code&gt;CompositeFuture.all&lt;/code&gt;, that will succeed only when all the messages are completed, and only in this case the next polling can be made.&lt;br&gt;
If at least one of the future fails, everything will fail, and the polling will stop.&lt;br&gt;
There are various solutions that can be adopted to make the service handle the failure, e.g. sending the message to a &lt;a href="https://en.wikipedia.org/wiki/Dead_letter_queue" rel="noopener noreferrer"&gt;Dead Letter Queue&lt;/a&gt;, but we will not cover this case.&lt;/p&gt;

&lt;p&gt;The problem with this code is that if a message fails, we will lose it, because the consumer is set to auto-commit, so, it's vertx that commits the topic offset.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainVerticle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractVerticle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JDBCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datasourceConfiguration&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;KafkaConsumer&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;,&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="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumer&lt;/span&gt;&lt;br&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;,&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="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;&lt;br&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"topic.name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;poll&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumer&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;,&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="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KafkaConsumerRecords&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;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;pollPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;()&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;List&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;Future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;UpdateResult&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;futures&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;IntStream&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;range&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="mi"&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;size&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;())&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;mapToObj&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="nl"&amp;gt;records:&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;:&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;recordAt&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;map&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;persist&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;))&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;collect&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;toList&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;());&amp;lt;/span&amp;gt;

    &amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;CompositeFuture&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;all&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="k"&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;ArrayList&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;futures&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;));&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onSuccess&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;composite&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;out&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"All messages persisted"&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class="n"&amp;gt;poll&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onFailure&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;err&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"Error persisting messages: "&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;))&amp;lt;/span&amp;gt;
&amp;lt;span class="o"&amp;gt;;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;BOOTSTRAP_SERVERS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"kafkahost:9092"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;KEY_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;VALUE_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h4&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Manual commit&lt;br&gt;
&lt;/h4&gt;

&lt;p&gt;Setting the &lt;code&gt;ENABLE_AUTO_COMMIT_CONFIG&lt;/code&gt; properties to &lt;code&gt;false&lt;/code&gt;, the service takes ownership of the topic offset commit.&lt;br&gt;
The commit will be performed only when every message will be persisted, with this trick the &lt;code&gt;at least once&lt;/code&gt; delivery is achieved.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainVerticle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractVerticle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JDBCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datasourceConfiguration&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;KafkaConsumer&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;,&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="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumer&lt;/span&gt;&lt;br&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;,&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="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;&lt;br&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"topic.name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startPromise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;poll&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumer&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;,&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="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KafkaConsumerRecords&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;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;pollPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;()&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;List&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;Future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;UpdateResult&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;futures&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;IntStream&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;range&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="mi"&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;size&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;())&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;mapToObj&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="nl"&amp;gt;records:&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;:&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;recordAt&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;map&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;persist&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;))&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;collect&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;toList&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;());&amp;lt;/span&amp;gt;

    &amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;CompositeFuture&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;all&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="k"&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;ArrayList&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;futures&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;));&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;composite&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;Promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;Void&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;Promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;commit&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;();&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onSuccess&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;any&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;out&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"All messages persisted and committed"&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class="n"&amp;gt;poll&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onFailure&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;err&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"Error persisting and committing messages: "&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;))&amp;lt;/span&amp;gt;
&amp;lt;span class="o"&amp;gt;;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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;kafkaConsumerConfiguration&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&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;,&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="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;BOOTSTRAP_SERVERS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"kafkahost:9092"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENABLE_AUTO_COMMIT_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;KEY_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;VALUE_DESERIALIZER_CLASS_CONFIG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StringDeserializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h4&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Bonus feature: achieve ordering&lt;br&gt;
&lt;/h4&gt;

&lt;p&gt;With a little effort it's possible to achieve ordering:&lt;br&gt;
&lt;a href="https://dev.to/cherrychain/future-composition-in-vert-x-3gp8"&gt;future composition&lt;/a&gt; allows forcing every persist operation to wait the completion of its precedent.&lt;br&gt;
It's achievable by chaining the async computations one to another, so every one will be executed when the precedent future succeeds.&lt;br&gt;
This is a smart pattern to be used when &lt;code&gt;serialization&lt;/code&gt; is needed.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainVerticle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractVerticle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JDBCClient&lt;/span&gt; &lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;KafkaConsumer&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;,&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="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KafkaConsumerRecords&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;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pollPromise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;pollPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;()&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;IntStream&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;range&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="mi"&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;records&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;size&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;())&amp;lt;/span&amp;gt;
    &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;mapToObj&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="nl"&amp;gt;records:&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;:&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;recordAt&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt;
    &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;reduce&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;Future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;UpdateResult&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;succeededFuture&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(),&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;acc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;acc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;it&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;persist&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;record&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)),&amp;lt;/span&amp;gt;
      &amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;a&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;b&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;a&amp;lt;/span&amp;gt;
    &amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;)&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;compose&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;composite&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;Promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class="nc"&amp;gt;Void&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;Promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;promise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;();&amp;lt;/span&amp;gt;
    &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;commit&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;commitPromise&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;future&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;();&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onSuccess&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;any&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;out&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"All messages persisted and committed"&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
    &amp;lt;span class="n"&amp;gt;poll&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;jdbc&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;consumer&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;);&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;})&amp;lt;/span&amp;gt;
  &amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;onFailure&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;System&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;err&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;println&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"Error persisting and committing messages: "&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;+&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;cause&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;));&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h4&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h4&gt;

&lt;p&gt;Backpressure is a fundamental topic to cover when working with async programming.&lt;br&gt;
It does not come for free out of the vert.x box, but it can be acheived with some simple tricks.&lt;/p&gt;

</description>
      <category>vertx</category>
      <category>backpressure</category>
      <category>java</category>
      <category>async</category>
    </item>
    <item>
      <title>Introduction to Vert.x</title>
      <dc:creator>Piero</dc:creator>
      <pubDate>Fri, 19 Jun 2020 07:56:35 +0000</pubDate>
      <link>https://dev.to/cherrychain/introduction-to-vert-x-37nb</link>
      <guid>https://dev.to/cherrychain/introduction-to-vert-x-37nb</guid>
      <description>&lt;p&gt;What is Vert.x? What is it for?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vert.x&lt;/strong&gt; is a multi-language toolkit based on the JVM and used in software applications to implement &lt;br&gt;
asynchronous and event driven structures.&lt;br&gt;
However, to better understand its use, we must take a step back and explain what asynchronous programming is.&lt;/p&gt;
&lt;h3&gt;
  
  
  Asynchronous Programming
&lt;/h3&gt;

&lt;p&gt;Usually a program executes instructions sequentially on a single thread and while a function is running, &lt;br&gt;
it waits for it to finish before continuing with the next instruction, this is known as &lt;strong&gt;blocking execution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Task B blocking execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Main Thread:        |_Task A_| --&amp;gt; |______Task B______| --&amp;gt; |_Task C_|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Fortunately, modern computers are equipped with processors that are made of multiple cores that can execute instructions &lt;br&gt;
in parallel (multithreading). A program can therefore proceed normally on the main thread while one of its &lt;br&gt;
functions executes its own code on another thread in parallel. &lt;br&gt;
However, the process is still &lt;strong&gt;synchronous&lt;/strong&gt;, because if the main thread at some point needs the result of the &lt;br&gt;
function on the other thread, and the calculation is still ongoing, then an exception is thrown.&lt;/p&gt;

&lt;p&gt;Task C ends after the start of task D then an exception is thrown (task D needs the result of task C):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Main Thread:        |_Task A_| --&amp;gt; |_Task B_| --&amp;gt; |_Task D_| --&amp;gt; exception
 Secondary Thread:              --&amp;gt; |______Task C______| 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To solve this problem, &lt;strong&gt;asynchronous programming&lt;/strong&gt; comes into play with the use of special APIs, which allow you to define actions to be performed as soon as the result of a specific function becomes available.&lt;/p&gt;

&lt;p&gt;Task C generates the promise of a value while Task D knows that it must wait for this asynchronous result before processing its code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Main Thread:        |_Task A_| --&amp;gt; |_Task B_| --&amp;gt; async-result --&amp;gt; |_Task D_|
 Promise:                       --&amp;gt; |______Task C______| 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One tool that allows you to use the asynchronous programming is Vert.x&lt;/p&gt;

&lt;h3&gt;
  
  
  Vert.x is
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;highly modular&lt;/strong&gt; and consists of several components that can be used according to one's needs, in fact it cannot be defined as a framework, rather it should be considered a set of libraries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;light&lt;/strong&gt; (the core is about 650kB), high-performance and simple to use. Therefore, ideal for the development of microservices and more ...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;polyglot&lt;/strong&gt;, so it supports several languages: Java, Kotlin, JavaScript, Groovy, Ruby, Scala, Ceylon.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What does it offer?
&lt;/h3&gt;

&lt;h5&gt;
  
  
  The most used modules:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core&lt;/strong&gt;: basic functionality with support for HTTP, TCP, file system access and various other features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web&lt;/strong&gt;: tool-kit to write sophisticated web applications and HTTP microservices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data&lt;/strong&gt; Access: asynchronous clients that can be used to access your PostgreSql, MySql, MongoDb, ...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: integration and support of unit tests on asynchronous code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; and &lt;strong&gt;Authorisation&lt;/strong&gt;: provides API for authentication and authorization with JWT, OAuth 2, JDBC auth, Mongo auth, ...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Devops&lt;/strong&gt;: offers several components to monitoring the app while it runs in production (metrics, health checks, ...)&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Other modules:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reactive&lt;/strong&gt;: add-ons to make an application even more responsive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices&lt;/strong&gt;: components to build applications based on microservices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MQTT&lt;/strong&gt;: provides clients and servers which are able to open, manage and close a communication through MQTT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Messaging&lt;/strong&gt;: provides clients and servers which are able to communicate via AMQP, STOMP or RabbitMQ protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt;: provides clients to interact with Apache Kafka, Consul or send SMTP emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Bus Bridge&lt;/strong&gt;: offers several "bridges" to extend the use of the Event Bus outside the app via TCP ports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clustering&lt;/strong&gt;: supports different types of clustering (Hazelcast, Infinispan, Apache Ignite, Apache Zookeeper).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Services&lt;/strong&gt;: useful services for encapsulating reusable functionality in other places, which are distributed using an identifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud&lt;/strong&gt;: tool to build an OpenShift platform for cloud applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced&lt;/strong&gt;: advanced tools to be used in particular projects but which are not normally used.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Asynchronous Programming in Vert.x
&lt;/h3&gt;

&lt;p&gt;To understand how Vert.x allows implementing asynchronous programming, two key concepts must be clarified: what is a Verticle and what are Event Buses for?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verticle&lt;/strong&gt; is the deployment unit in Vert.x, which processes incoming events using an &lt;strong&gt;Event Loop&lt;/strong&gt; on a specific Thread. By default, two Event Loops are connected to each Thread Core of the CPU. A Verticle can be instantiated several times.&lt;/p&gt;

&lt;p&gt;On the other hand, when we talk about &lt;strong&gt;Events&lt;/strong&gt; we mean, for example, the reception of "network buffers", "timing events" or the reception of messages from other Verticles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K6mpmVEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vertx.io/docs/guide-for-java-devs/intro/images/event-loop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K6mpmVEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vertx.io/docs/guide-for-java-devs/intro/images/event-loop.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Event Bus&lt;/strong&gt; is the communication channel that Verticles used to send messages asynchronously. The type of data exchanged can be of any type, but it is preferable to use the JSON format since it can be understood by all languages.&lt;/p&gt;

&lt;p&gt;The supported communication patterns are: Point-to-Point messaging (direct message), Request / Response messaging and Publish / Subscribe messaging (to send messages in broadcast).&lt;/p&gt;

&lt;p&gt;The Event Bus can also be distributed, meaning Verticles that are not necessarily running on the same machine can communicate with each other. In addition, thanks to the "bridges" it can also communicate with generic messaging protocols such as AMQP and STOMP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oz3ZQ1Nc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vertx.io/docs/guide-for-java-devs/intro/images/event-bus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oz3ZQ1Nc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vertx.io/docs/guide-for-java-devs/intro/images/event-bus.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After understanding the architecture behind Vert.x, now let's try to understand the two main constructs of asynchronous programming: Promise and Future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Promise and Future
&lt;/h3&gt;

&lt;p&gt;In abstract terms, Future and Promise can be thought of as values that at a certain point in time become available and therefore require a certain amount of time to be calculated or retrieved. For this reason, two states in which a Future / Promise can be found are generally recognized: Completed / Determined when the value is available or Incomplete / Indeterminate when the value has not yet been calculated.&lt;/p&gt;

&lt;p&gt;In Vert.x there are Promise and Future constructs that refer to these abstractions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Future&lt;/strong&gt;: reference, read-only, at a value yet to be calculated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promise&lt;/strong&gt;: variable, assignable only once, to which Future refers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, a Future shows the value previously written in a Promise in read-only mode.&lt;/p&gt;

&lt;p&gt;NOTE: do not confuse Vert.x futures with Java ones!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So in conclusion Vert.x is a very useful tool that allows us to use asynchronous programming in different areas and&lt;br&gt;
which however carries some advantages and disadvantages.&lt;/p&gt;

&lt;p&gt;Strengths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;scalability&lt;/strong&gt;, being modular allows it to be used only where it is deemed necessary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;microservices&lt;/strong&gt;, being light but at the same time performing it is ideal for the development of microservices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;versatility&lt;/strong&gt;, by supporting different languages you are not bound to use one that you don't know or don't like&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Weaknesses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;learning curve&lt;/strong&gt;, it takes time to fully understand the mechanisms behind the Vert.x modules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;backpressure&lt;/strong&gt;, which must be managed to avoid memory problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;delays&lt;/strong&gt;, if an event is not properly handled it can generate unexpected delays&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Authors: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dev.to/atipij&lt;/li&gt;
&lt;li&gt;dev.to/piero90 &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>vertx</category>
      <category>async</category>
    </item>
    <item>
      <title>Future Composition in Vert.x</title>
      <dc:creator>ndr_brt</dc:creator>
      <pubDate>Wed, 20 May 2020 11:42:45 +0000</pubDate>
      <link>https://dev.to/cherrychain/future-composition-in-vert-x-3gp8</link>
      <guid>https://dev.to/cherrychain/future-composition-in-vert-x-3gp8</guid>
      <description>&lt;p&gt;For those who don't know, Vert.x is an event driven and non blocking application toolkit.&lt;br&gt;
It's polyglot, so you can use it with different languages (as &lt;strong&gt;Java&lt;/strong&gt;, &lt;strong&gt;Kotlin&lt;/strong&gt;, &lt;strong&gt;JavaScript&lt;/strong&gt;, &lt;strong&gt;Groovy&lt;/strong&gt;, &lt;strong&gt;Ruby&lt;/strong&gt; or &lt;strong&gt;Scala&lt;/strong&gt;).&lt;/p&gt;
&lt;h3&gt;
  
  
  What does "non blocking" mean?
&lt;/h3&gt;

&lt;p&gt;In synchronous programming, when a function is called, the caller has to wait until the result is returned. &lt;br&gt;
This behaviour could lead to performance issues.&lt;/p&gt;

&lt;p&gt;Often the "obvious solution" seems to be &lt;a href="https://en.wikipedia.org/wiki/Concurrent_computing"&gt;concurrent programming&lt;/a&gt;, but dealing with shared resources and threads is not easy and deadlocks are around the corner.&lt;/p&gt;

&lt;p&gt;Explaining how Vert.x guarantees asynchrony through the &lt;strong&gt;event loop&lt;/strong&gt; concept is not in the scope of this article, but anything you may want to know gets unraveled in the great &lt;a href="https://vertx.io/docs/guide-for-java-devs/"&gt;Gentle guide to async programming with Vert.x&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In a "non blocking" world, when the result of a function can be provided immediately, it will be. Otherwise a handler is provided to handle it when it will be ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;asyncFunctionCall&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;doSometingWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;Usualy a big "but" gets raised the first time an async piece of code is seen: &lt;em&gt;But... I need that result now!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This kind of programming requires a mindset change: it's necessary to know and understand the main patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Futures vs Callbacks
&lt;/h3&gt;

&lt;p&gt;There are two ways to deal with async calls in Vert.x.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pass a callback that will be executed on call completion.&lt;/li&gt;
&lt;li&gt;Handle a future returned from the function/method call.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Callback
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;asyncResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// do stuff with result&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// handle failure&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;A callback is a function passed to an async method used to handle the result of its computation.&lt;br&gt;
It's simple to implement but it brings some drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit testing becomes not-so-immediate&lt;/li&gt;
&lt;li&gt;Leads to the dreaded &lt;a href="http://callbackhell.com/"&gt;Callback Hell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;There's more code to be written.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Future
&lt;/h4&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Future&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// handle failure&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To avoid the problems listed for the "callback way", Vert.x implements a concept called &lt;strong&gt;Future&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A future is an object that &lt;strong&gt;represents the result of an action that may, or may not, have occurred yet&lt;/strong&gt; (cf. &lt;a href="https://vertx.io/docs/apidocs/io/vertx/core/Future.html"&gt;apidoc&lt;/a&gt;).&lt;/p&gt;
&lt;h5&gt;
  
  
  How to switch from a callback-like call to a future one
&lt;/h5&gt;

&lt;p&gt;Consider the callback example shown above. &lt;br&gt;
We want a Future object to take advantage of the patterns described below, but &lt;code&gt;asyncComputation&lt;/code&gt; is a function from another library, so we cannot modify it.&lt;/p&gt;

&lt;p&gt;We can use a &lt;strong&gt;Promise&lt;/strong&gt;.&lt;br&gt;
According to the &lt;a href="https://vertx.io/docs/apidocs/io/vertx/core/Promise.html"&gt;apidoc&lt;/a&gt;, it &lt;strong&gt;represents the writable side of an action that may, or may not, have occurred yet.&lt;/strong&gt;&lt;br&gt;
It perfectly fits our needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeeded&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cause&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. We transformed a callback into a future.&lt;br&gt;
The Promise API's give us a way to make this code more readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;promise:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;handle&lt;/em&gt; method takes care of the completion or failure of the promise, given an async result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future patterns
&lt;/h3&gt;

&lt;p&gt;The Future object implements some interesting patterns that smartly help resolving async issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map&lt;/li&gt;
&lt;li&gt;Compose&lt;/li&gt;
&lt;li&gt;Recover&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Future Mapping
&lt;/h4&gt;

&lt;p&gt;For those of you who know about the &lt;code&gt;map&lt;/code&gt; function, part of the java &lt;code&gt;Stream&lt;/code&gt; API, this feature should be immediate to understand.&lt;/p&gt;

&lt;p&gt;The Future's map function accepts a function that transforms the result from one type to another.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// returns a Future&amp;lt;String&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns a Future&amp;lt;Integer&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Future Composition
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;compose&lt;/code&gt; method is similar to &lt;code&gt;map&lt;/code&gt;, but is used when the mapping is an async operation itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;retrieveDataById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// retrieveDataById returns a Future&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Future Recovery
&lt;/h4&gt;

&lt;p&gt;Futures can succeed, but can also fail. &lt;br&gt;
To handle a failed future and consider a different behaviour, &lt;code&gt;recover&lt;/code&gt; function can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;asyncComputation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recover&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;succeededFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// when Integer::valueOf fails, the future could be recovered with a default value&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;retrieveDataById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Concurrent composition
&lt;/h4&gt;

&lt;p&gt;To handle multiple future results at the same time, &lt;code&gt;CompositeFuture&lt;/code&gt; is the class needed, it provides two static factory methods:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;all&lt;/code&gt; returns a future that succeeds if all the futures passed as parameters succeed, and fails if at least one fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompositeFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;futureOne&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;futureTwo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compositeResult&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// all futures succeeded&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="c1"&gt;// at least one failed&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;any&lt;/code&gt; returns a future that succeeds if any one of the futures passed as parameters succeed, and fails if all fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompositeFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;futureOne&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;futureTwo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compositeResult&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// at least one succeed&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onFailure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="c1"&gt;// all failed&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;Future composition API in Vert.x represents a solid way to write simple and affordable async code.&lt;br&gt;
Always remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;never throw exceptions into async code, use failed future instead to handle failure behaviours.&lt;/li&gt;
&lt;li&gt;at the end of a future composition, don't forget to handle future's successes (&lt;code&gt;onSuccess&lt;/code&gt;) and failures (&lt;code&gt;onFailure&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vertx</category>
      <category>async</category>
      <category>java</category>
    </item>
  </channel>
</rss>
