<?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: Sonu Kumar</title>
    <description>The latest articles on DEV Community by Sonu Kumar (@sonus21).</description>
    <link>https://dev.to/sonus21</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F641114%2Ff445d6b6-da8a-43de-8722-8fada4799b4c.jpeg</url>
      <title>DEV Community: Sonu Kumar</title>
      <link>https://dev.to/sonus21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sonus21"/>
    <language>en</language>
    <item>
      <title>KUID: Compressed Universally Unique Identifier</title>
      <dc:creator>Sonu Kumar</dc:creator>
      <pubDate>Sun, 26 Feb 2023 05:55:05 +0000</pubDate>
      <link>https://dev.to/sonus21/kuid-compressed-universally-unique-identifier-384i</link>
      <guid>https://dev.to/sonus21/kuid-compressed-universally-unique-identifier-384i</guid>
      <description>&lt;p&gt;KUID, a universally unique identifier, is essentially a shorter version of a UUID and is commonly used to identify records in various applications.&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%2Fjv7cklpn2tl7nmmmhqc8.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%2Fuploads%2Farticles%2Fjv7cklpn2tl7nmmmhqc8.jpg" alt="KUID"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's UUID?
&lt;/h2&gt;

&lt;p&gt;A UUID (Universally Unique Identifier) is a unique identifier that is widely used across various applications and systems to identify records. It is a 128-bit number typically represented as a sequence of 32 hexadecimal digits, grouped in 5 sections, separated by hyphens, as in the following format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.&lt;/p&gt;

&lt;p&gt;UUIDs are designed to be globally unique, meaning that it is extremely unlikely for two UUIDs to be the same, even when generated independently by different systems. This makes UUIDs useful for identifying and tracking records in distributed systems, databases, and other contexts where unique identification is necessary.&lt;/p&gt;

&lt;p&gt;There are different variants and versions of UUIDs, each with its own way of generating unique identifiers. Some commonly used variants include UUIDv1, UUIDv4, and UUIDv5. The specific variant and version of a UUID can be determined from the format and content of the identifier.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to generate KUID?
&lt;/h2&gt;

&lt;p&gt;KUID is generated in two steps&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate UUID (use any algorithm like V1,V2,V3,V4 etc)&lt;/li&gt;
&lt;li&gt;Encode 128-bit number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;KUID = Generate UUID and encode it in the higher base like base 32, 62 or even higher.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The length of the KUID depends on the encoding scheme employed. If the base62 encoding scheme ([0–9A-Za-z]) is used, KUID can be encoded to 22 bytes. However, if you wish to store KUID in upper case, then encoding it using the base36 encoding scheme, which utilizes characters [0–9A-Z], will result in an encoded representation that can be stored in 26 bytes. For this post, we'll use base 62 encoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should we use KUID?
&lt;/h2&gt;

&lt;p&gt;KUID generates a smaller string, which results in less storage space and faster processing of many operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE: Following statements are only valid when KUID is treated as a string, not as 128-bit number.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hashing&lt;/strong&gt;: Using KUID with its shorter length of 22 bytes reduces the amount of data that needs to be hashed. This results in fewer instructions being required to perform the hashing operation compared to UUID, which requires a hash of 36 bytes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison&lt;/strong&gt;: Due to the shorter length of KUID, only 22 bytes need to be compared instead of 36 bytes, resulting in fewer instructions needed for comparison.
Read/Write: Using KUID, which can be encoded in 22 bytes, results in a reduction in the memory and disk space required for read and write operations. This is in contrast to UUID, which requires 36 bytes for the same operations. With KUID, fewer instructions are needed to read or write data due to its smaller size.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I/O Calls&lt;/strong&gt;: Sending a UUID over a network consumes 36 bytes of data (without considering compression), while a KUID only requires 22 bytes. Therefore, KUID is a more efficient choice for network transmission due to its smaller size.&lt;br&gt;
Database indexing: Due to the smaller size of KUID, it leads to a decrease in the size of the database index. In addition, combining KUID with another column for secondary indexing can be beneficial as databases have a limited index width (e.g., 767 bytes in MySQL) that is dependent on the encoding used for the column or table. For instance, MySQL's UTF8 encoding may limit the index width to as little as 255 bytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL safe&lt;/strong&gt;: Like UUID, KUID is URL safe since it only uses [0–9A-Za-z] characters to represent the data. KUID is commonly used as a unique column, which means that URLs containing KUIDs may be used to represent specific resources, such as /api/v1/products/:productId. As the KUID is included in the URL, it must be URL safe to avoid issues such as encoding errors or unintended interpretation by the web server or browser.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lower Memory/Disk Usage&lt;/strong&gt;: Using KUID results in lower memory/disk usage compared to UUID. Since KUID only requires 22 bytes, it uses less storage space than UUID, which uses 36 bytes. This can be beneficial for systems that require frequent read/write operations or have limited storage capacity. For instance, if we consider the storage of 100 million records, assuming each KUID is stored as a 22-byte string, the space consumed by KUIDs would be approximately 2.2 GB. In contrast, the space required for UUIDs would be around 3.6 GB. Therefore, using KUIDs can result in a storage saving of approximately 39%.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;KUID Usage&lt;/p&gt;

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

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i &amp;lt; 10; i++) {
            KUID kuid = KUID.randomKUID();
            System.out.println(kuid.toString());
        }

    }
}



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

&lt;/div&gt;
&lt;p&gt;This will produce something like this&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;If you found this post helpful, please share and give a thumbs up.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>performance</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Asynchronous task execution using Redis and Spring(Boot)</title>
      <dc:creator>Sonu Kumar</dc:creator>
      <pubDate>Mon, 31 May 2021 17:42:51 +0000</pubDate>
      <link>https://dev.to/sonus21/asynchronous-task-execution-using-redis-and-spring-boot-2efd</link>
      <guid>https://dev.to/sonus21/asynchronous-task-execution-using-redis-and-spring-boot-2efd</guid>
      <description>&lt;p&gt;In this article, we are going to see how to use Spring boot 2.x and Redis to execute asynchronous tasks, with the final code that we will have after following the steps described here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spring/Spring Boot
&lt;/h2&gt;

&lt;p&gt;Spring is the most popular framework available for the Java platform. Spring has one of the largest communities in open source. Besides that, Spring provides extensive and up-to-date documentation that covers the inner workings of the framework and sample projects on their blog, there’re 100K+ questions on StackOverflow.&lt;br&gt;
Spring 3.0 was the first version that supported the annotation-based configuration, later in 2014 Spring boot 1.0 was released that completely changed how we look at the Spring framework ecosystems, it provides out of the box configuration and many more. Timeline&lt;/p&gt;

&lt;h2&gt;
  
  
  Redis
&lt;/h2&gt;

&lt;p&gt;Redis is one of the most popular open-source NoSQL in-memory database. Redis supports different types of data structures e.g. Set, Hash table, List, simple key-value pair just name a few. The latency of Redis call is sub-milliseconds, support of a replica set, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Asynchronous task execution
&lt;/h2&gt;

&lt;p&gt;A typical API call consists of five things&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute one or more database(RDBMS/NoSQL) queries&lt;/li&gt;
&lt;li&gt;One or more operations on some cache systems (In-Memory, Distributed, etc )&lt;/li&gt;
&lt;li&gt;Some computations (it could be some data crunching doing some math operations)&lt;/li&gt;
&lt;li&gt;Calling some other service(s) (internal/external)&lt;/li&gt;
&lt;li&gt;Schedule one or more tasks to be executed at a later time or immediately but in the background.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A task can be scheduled at a later time for many reasons for example invoice must be generated after 7 days of order creation or order shipment, similarly, email/notification(s) need not be sent immediately it can be delayed. Sometimes we need to execute tasks in asynchronous to reduce API response time, for example, delete 1K+ records at once if we delete all these records in the same API call then API response time would be increased for sure, to reduce API response time, we can run a task in the background that would delete those records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delayed queue
&lt;/h2&gt;

&lt;p&gt;We can run schedule tasks using cron jobs, a cron job can be scheduled using different methods like UNIX style crontabs, Chronos, if we’re using Spring frameworks then it’s out of box Scheduled annotation ❤️. Most of these scheduling mechanisms suffer scaling problems, where we do scan database(s) to find the relevant rows/records. In many situations, this leads to a full table scan which performs very poorly. Imagine the case where the same database is used by a real-time application and this batch processing system. A delayed queue can be used in such cases where as soon as the timer reaches the scheduled time a job would be triggered. There’re many queuing systems/software available, but very few of them provide this feature, like SQS which provides a delay of 15 minutes, not an arbitrary delay like 7 hours or 7 days.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rqueue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sonus21/rqueue" rel="noopener noreferrer"&gt;Rqueue&lt;/a&gt; is a broker built for the spring framework that stores data in Redis and provides a mechanism to execute a task at any arbitrary delay. Rqueue is backed by Redis since Redis has some advantages over the widely used queuing systems like Kafka, SQS. In most web applications backend, Redis is used to store either cache data orother purposese. In today's world, &lt;a href="https://scalegrid.io/blog/2019-database-trends-sql-vs-nosql-top-databases-single-vs-multiple-database-use/" rel="noopener noreferrer"&gt;8.4%&lt;/a&gt; of web applications are using the Redis database.&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%2Ftioo4vz6zlm2383q0qu5.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%2Fuploads%2Farticles%2Ftioo4vz6zlm2383q0qu5.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generally, for a queue, we use either Kafka/SQS or some other systems these systems bring an additional overhead in different dimensions e.g money which can be reduced to zero using Rqueue and Redis.&lt;/p&gt;

&lt;p&gt;Apart from the cost if we use Kafka then we need to do infrastructure setup, maintenance i.e. more ops, as most of the applications are already using Redis so we won’t have ops overhead, in fact, same Redis server/cluster can be used with Rqueue. Rqueue supports an arbitrary delay&lt;/p&gt;

&lt;p&gt;Message Delivery&lt;br&gt;
Rqueue guarantee at-least-once message delivery as long data is not wiped out from Redis. Read about it more at &lt;a href="https://medium.com/@sonus21/introducing-rqueue-redis-queue-d344f5c36e1b" rel="noopener noreferrer"&gt;Introducing Rqueue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tools we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Any IDE 2. Gradle 3. Java 4. Redis
We’re going to use Spring boot for simplicity, we’ll create a Gradle project from spring boot initializer at &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;https://start.spring.io/&lt;/a&gt;, for dependency we would need

&lt;ol&gt;
&lt;li&gt;Spring Data Redis 2. Spring Web 3. Lombok and any others. &lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;The directory/folder structure would look like below.&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%2F2epyidxh1qfv5cbv1cua.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%2F2epyidxh1qfv5cbv1cua.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re going to use the Rqueue library to execute any tasks with any arbitrary delay. Rqueue is a Spring-based asynchronous task executor, that can execute tasks at any delay, it’s built upon the Spring messaging library and backed by Redis.&lt;br&gt;
We’ll add the Rqueue spring boot starter dependency using com.github.sonus21:rqueue-spring-boot-starter:2.7.0-RELEASE&lt;/p&gt;

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

&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-data-redis'&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-web'&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.github.sonus21:rqueue-spring-boot-starter:2.7.0-RELEASE'&lt;/span&gt;
    &lt;span class="n"&gt;compileOnly&lt;/span&gt; &lt;span class="s1"&gt;'org.projectlombok:lombok'&lt;/span&gt;
    &lt;span class="n"&gt;annotationProcessor&lt;/span&gt; &lt;span class="s1"&gt;'org.projectlombok:lombok'&lt;/span&gt;
    &lt;span class="n"&gt;providedRuntime&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-tomcat'&lt;/span&gt;
    &lt;span class="n"&gt;testImplementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-test'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;exclude&lt;/span&gt; &lt;span class="nl"&gt;group:&lt;/span&gt; &lt;span class="s1"&gt;'org.junit.vintage'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;module:&lt;/span&gt; &lt;span class="s1"&gt;'junit-vintage-engine'&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 enable Redis spring boot features, for testing purposes we will enable WEB MVC as well.&lt;br&gt;
Update Application file as&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;@SpringBootApplication&lt;/span&gt;
&lt;span class="nd"&gt;@EnableRedisRepositories&lt;/span&gt;
&lt;span class="nd"&gt;@EnableWebMvc&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsynchronousTaskExecutorApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&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="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AsynchronousTaskExecutorApplication&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;args&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;Adding tasks using Rqueue is very simple we need to just annotate a method with RqueueListener. RqueuListener annotation has multiple fields that can be set based on the use case, for example, set deadLetterQueue to push tasks to another queue otherwise task will be discarded on failure. We can also set how many times a task should be retried using the numRetries field.&lt;br&gt;
Create a Java file name MessageListener and add some methods to execute tasks.&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.github.sonus21.rqueue.annotation.RqueueListener&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.extern.slf4j.Slf4j&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="nd"&gt;@Slf4j&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MessageListener&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@RqueueListener&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"${email.queue.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;email&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;"Email {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@RqueueListener&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"${invoice.queue.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;generateInvoice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="n"&gt;invoice&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;"Invoice {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invoice&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;We would need Email and Invoice classes to store email and invoice data respectively. For simplicity, classes would only have a handful number of fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invoice.java&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.AllArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.NoArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;type&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;strong&gt;Email.java&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.AllArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.NoArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;content&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;h2&gt;
  
  
  Task submissions
&lt;/h2&gt;

&lt;p&gt;A task can be submitted using the &lt;code&gt;RqueueMessageEnqueuer&lt;/code&gt; bean. This has multiple methods to enqueue tasks depending on the use case, like retry use, retry count, and delay for delayed tasks.&lt;/p&gt;

&lt;p&gt;We need to AutoWire &lt;code&gt;RqueueMessageEnqueuer&lt;/code&gt; or use constructor to inject this bean.&lt;/p&gt;

&lt;p&gt;Create a Controller for testing purpose:&lt;br&gt;
We’re going to schedule invoice generation that would be done in the next 30 seconds, for this we’ll submit a task with 30000 (milliseconds) delay on invoice queue. Also, we’ll try to send an email that will be done in the background. For this purpose, we’ll add two GET methods &lt;code&gt;sendEmail&lt;/code&gt; and &lt;code&gt;generateInvoice&lt;/code&gt;, we can use POST as well.&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;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onConstructor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@__&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="nd"&gt;@Slf4j&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;RqueueMessageEnqueuer&lt;/span&gt; &lt;span class="n"&gt;rqueueMessageEnqueuer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${email.queue.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;emailQueueName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${invoice.queue.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;invoiceQueueName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${invoice.queue.delay}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;invoiceDelay&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;content&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;"Sending email"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;rqueueMessageEnqueuer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enqueue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emailQueueName&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;Email&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Please check your inbox!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateInvoice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;type&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;"Generate invoice"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;rqueueMessageEnqueuer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enqueueIn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invoiceQueueName&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;Invoice&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="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;invoiceDelay&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Invoice would be generated in "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;invoiceDelay&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" milliseconds"&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;Add the following in the application.properties file&lt;/p&gt;

&lt;p&gt;email.queue.name=email-queue&lt;br&gt;
invoice.queue.name=invoice-queue&lt;/p&gt;

&lt;h1&gt;
  
  
  30 seconds delay for invoice
&lt;/h1&gt;

&lt;p&gt;invoice.queue.delay=300000&lt;/p&gt;

&lt;p&gt;It’s time to fire up the spring boot application, once the application starts successfully, browse&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:8080/email?email=xample@exampl.com&amp;amp;subject=%22test%20email%22&amp;amp;content=%22testing%20email%22" rel="noopener noreferrer"&gt;http://localhost:8080/email?email=xample@exampl.com&amp;amp;subject=%22test%20email%22&amp;amp;content=%22testing%20email%22&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the log, we can see tasks are being executed in the background&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%2Fnqn52grau7wjlivfor5s.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%2Fnqn52grau7wjlivfor5s.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invoice scheduling after 30 seconds&lt;br&gt;
&lt;a href="http://localhost:8080/invoice?id=INV-1234&amp;amp;type=PROFORMA" rel="noopener noreferrer"&gt;http://localhost:8080/invoice?id=INV-1234&amp;amp;type=PROFORMA&lt;/a&gt;&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%2Figjwemaupaxfng0pl6hc.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%2Figjwemaupaxfng0pl6hc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, we can schedule tasks using Rqueue without much of the boiler code. We need to consider a few things while configuring the Rqueue library and using them. One of the important is whether a task is a delayed task or not; by default, it’s assumed tasks need to be executed as soon as possible.&lt;/p&gt;

&lt;p&gt;Complete code can be found at my Github account &lt;a href="https://github.com/sonus21/rqueue-task-exector" rel="noopener noreferrer"&gt;https://github.com/sonus21/rqueue-task-exector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rqueue library code: &lt;a href="https://github.com/sonus21/rqueue" rel="noopener noreferrer"&gt;https://github.com/sonus21/rqueue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this post helpful please share across and give a thumbs up.&lt;/p&gt;

</description>
      <category>spring</category>
    </item>
  </channel>
</rss>
