<?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: dikac</title>
    <description>The latest articles on DEV Community by dikac (@dikac).</description>
    <link>https://dev.to/dikac</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%2F1265636%2Fa141ac7f-0298-41a6-a36a-8b3947de8c78.png</url>
      <title>DEV Community: dikac</title>
      <link>https://dev.to/dikac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dikac"/>
    <language>en</language>
    <item>
      <title>Profiling Memory In Go</title>
      <dc:creator>dikac</dc:creator>
      <pubDate>Tue, 17 Dec 2024 02:00:47 +0000</pubDate>
      <link>https://dev.to/tentanganak/profiling-memory-in-go-2a2</link>
      <guid>https://dev.to/tentanganak/profiling-memory-in-go-2a2</guid>
      <description>&lt;p&gt;Efficient memory management is critical in Golang applications, particularly in high-concurrency environments, long-running services, or data-intensive tasks. Profiling memory usage helps diagnose issues, optimize performance, and prevent out-of-memory (OOM) errors. This guide provides a comprehensive approach to profiling memory usage from a Go endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Memory Profiling Matters
&lt;/h2&gt;

&lt;p&gt;Memory profiling identifies inefficient memory usage, memory leaks, and excessive allocations in your application. Without proper profiling, memory issues can lead to performance degradation, higher costs, and service downtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Causes of High Memory Usage
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory leaks&lt;/strong&gt;: Unintended memory retention due to data structures not being cleared up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excessive allocations&lt;/strong&gt;: Large slices, maps, or other data structures consuming significant memory.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Setting Up Memory Profiling in Go
&lt;/h2&gt;

&lt;p&gt;To profile memory usage in a Go application, you can use tools like &lt;code&gt;pprof&lt;/code&gt; for runtime profiling and &lt;code&gt;parca&lt;/code&gt; for continuous profiling. Here’s how to set up and use these tools effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Profiling Tools
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;pprof&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A built-in Go tool that provides profiling for memory, CPU, goroutines, and more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/net/http/pprof" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parca&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A continuous profiling tool that provides real-time insights by collecting data from &lt;code&gt;pprof&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stress Testing&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Generate load to simulate real-world usage and observe memory behavior under stress. For our case we use &lt;a href="https://www.soapui.org/" rel="noopener noreferrer"&gt;SoapUI&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;pprof&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Since &lt;code&gt;pprof&lt;/code&gt; is built-in tool, installation is not required, include the following snippet to enable &lt;code&gt;pprof&lt;/code&gt; in your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"net/http/pprof"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&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;This exposes &lt;code&gt;pprof&lt;/code&gt; on port &lt;code&gt;1234&lt;/code&gt;. Access profiling data by visiting &lt;code&gt;http://localhost:1234/debug/pprof/&lt;/code&gt; or using tools like &lt;code&gt;go tool pprof&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;parca&lt;/code&gt; for Continuous Profiling
&lt;/h3&gt;

&lt;p&gt;To install &lt;code&gt;parca&lt;/code&gt; see &lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;https://github.com/parca-dev/parca&lt;/a&gt;, after successfully installing &lt;code&gt;parca&lt;/code&gt;, configure &lt;code&gt;parca.yaml&lt;/code&gt; &lt;code&gt;job_name.static_configs.targets&lt;/code&gt; set the same port number as &lt;code&gt;pprof&lt;/code&gt; (in this example &lt;code&gt;1234&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;then you can run command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;parca &lt;span class="nt"&gt;--config-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"parca.yaml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if successful you will see message similar to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;level=info name=parca ts=2024-10-30T06:19:44.5149184Z caller=factory.go:53 msg="loading bucket configuration"
level=info name=parca ts=2024-10-30T06:19:44.5159183Z caller=badger.go:54 msg="Set nextTxnTs to 0"
level=info name=parca ts=2024-10-30T06:19:44.517917Z caller=server.go:90 msg="starting server" addr=:7070
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;addr=:7070&lt;/code&gt; is where you can access &lt;code&gt;parca&lt;/code&gt; web interface, port number might be different depend on configuration&lt;/p&gt;

&lt;p&gt;if all setup successful, you can access &lt;code&gt;parca&lt;/code&gt; on web browser&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fixnatctqisv5vrekkv1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fixnatctqisv5vrekkv1v.png" alt="Image description" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a multiple &lt;code&gt;profiling type&lt;/code&gt;, for Memory usage you can use&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F843qfkxx0xd83ivhm0sa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F843qfkxx0xd83ivhm0sa.png" alt="Image description" width="220" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;if you encounter any issue, you should consult documentation since different environment might require different solution&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pprof &lt;a href="https://pkg.go.dev/net/http/pprof" rel="noopener noreferrer"&gt;https://pkg.go.dev/net/http/pprof&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;parca &lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;https://github.com/parca-dev/parca&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Identifying Memory Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stress Testing
&lt;/h3&gt;

&lt;p&gt;Before profiling, simulate high traffic using stress-testing tools in our case we use &lt;a href="https://www.soapui.org/" rel="noopener noreferrer"&gt;SoapUI&lt;/a&gt;. Stress tests help replicate conditions leading to memory issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing Memory Usage
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;br&gt;
After completing a stress test, monitor memory usage over time using the &lt;code&gt;parca&lt;/code&gt; dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;br&gt;
Click on the graphs to access detailed profiles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2l2db0qsj2f0imjdu6xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2l2db0qsj2f0imjdu6xj.png" alt="Image description" width="800" height="405"&gt;&lt;/a&gt;&lt;br&gt;
Using the icicle graph, examine the stack and corresponding memory usage. Wider lines indicate higher &lt;strong&gt;memory&lt;/strong&gt; consumption. This visualization helps pinpoint processes consuming significant memory.&lt;/p&gt;

&lt;p&gt;In our application, a process with substantial memory usage was identified:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcjxzp9h88c6v3qw9yqie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcjxzp9h88c6v3qw9yqie.png" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory Optimization
&lt;/h3&gt;

&lt;p&gt;Memory optimization is a complex topic that varies depending on the application and its environment. Here are some practical techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selective Data Loading:&lt;/strong&gt; Load only the necessary data to significantly reduce memory allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoiding Pointers&lt;/strong&gt;: Use value types instead of pointers to minimize heap allocations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predefining Data Lengths&lt;/strong&gt;: Specify lengths for known-size data structures to improve memory efficiency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upon further investigation, we discovered that the data retrieved from the cache was excessively large. We needed to validate whether such a large dataset was truly necessary for our logic flow.&lt;/p&gt;

&lt;p&gt;In our case, it turned out that this large dataset was not required. Therefore, we optimized the process by &lt;strong&gt;selectively removing unnecessary data&lt;/strong&gt;. After re-running the tests, memory usage was reduced by approximately 50%.&lt;/p&gt;

&lt;p&gt;Previous Implementation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selectively removing unneeded data&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv8ggik8e3va6s86cce6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv8ggik8e3va6s86cce6z.png" alt="Image description" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With help of this method we can easily narrow down and correct memory usage, in our case &lt;strong&gt;Selective Data Loading&lt;/strong&gt; is the correct method for reducing memory usage.&lt;/p&gt;




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

&lt;p&gt;Memory profiling is a critical practice for maintaining the performance and stability of Go applications. By leveraging tools like &lt;code&gt;pprof&lt;/code&gt; and &lt;code&gt;parca&lt;/code&gt;, you can identify memory issues, optimize resource usage, and ensure your application performs reliably under various loads. Regular profiling and proactive optimization help address memory-related challenges effectively.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Handling Currency In Golang And Other Programming Language</title>
      <dc:creator>dikac</dc:creator>
      <pubDate>Fri, 28 Jun 2024 20:37:56 +0000</pubDate>
      <link>https://dev.to/tentanganak/handling-currency-in-golang-and-other-programming-language-518h</link>
      <guid>https://dev.to/tentanganak/handling-currency-in-golang-and-other-programming-language-518h</guid>
      <description>&lt;p&gt;Handling currency in programming languages is a critical aspect of software development, especially for applications dealing with financial transactions, e-commerce, banking, and accounting systems. Accurate representation and manipulation of currency values are essential to avoid errors that can lead to significant financial discrepancies. &lt;/p&gt;

&lt;p&gt;This article will explore best practices in handling currency with example in Go languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Precision and Accuracy
&lt;/h1&gt;

&lt;p&gt;One of the primary concerns when dealing with currency is precision. Unlike floating-point numbers, which can introduce rounding errors, currency values require precise representation. &lt;/p&gt;

&lt;p&gt;consider following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1.1&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1.2&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1.3&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&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;Above code would print&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Since memory of computers is limited, most programming language including Go store floating point based on the &lt;a href="https://en.wikipedia.org/wiki/IEEE_754"&gt;IEEE-754&lt;/a&gt; standard using 32 or 64 bits, even using 64-bit precision it’s impossible to store an infinite number of digits, which means these numbers are rounded at some point, making them inherently imprecise, and the more calculation is performed the more they become imprecise.&lt;/p&gt;

&lt;p&gt;There is many way to handle this problem like using 3rd party library or the programming language you use has a native support.  In Go, there are several libraries, including :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;shopspring/decimal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;ericlagergren/decimal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;alpacahq/alpacadecimal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;govalues/decimal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;credit to &lt;a href="https://dev.to/kennfatt"&gt;kennfatt&lt;/a&gt; for curating this library list&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Choosing Library
&lt;/h1&gt;

&lt;p&gt;Choosing the right library for handling currency programming involves several considerations. Here's a guide to help you choose an appropriate decimal library for your needs&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Accuracy and Precision
&lt;/h2&gt;

&lt;p&gt;Ensure the library supports precision and accuracy suit your requirement. Look for arbitrary precision capabilities if dealing with very large numbers or very precise calculations.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ease of Use
&lt;/h2&gt;

&lt;p&gt;The library should have clear and comprehensive documentation. It should be easy to integrate with your existing codebase and workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Performance
&lt;/h2&gt;

&lt;p&gt;Consider the performance impact, especially if you are performing a large number of calculations or operating in a high-frequency trading environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Feature
&lt;/h2&gt;

&lt;p&gt;Ensure the features suit with your needs, from basic arithmetic like rounding, addition, subtraction multiplication, division to more complex math operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Community and Support
&lt;/h2&gt;

&lt;p&gt;A well-supported library with an active community can be crucial for getting help and finding solutions to problems.    Look for libraries that are actively maintained and updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using 3rd Party
&lt;/h2&gt;

&lt;p&gt;This article will use 3rd party library &lt;code&gt;govalues/decimal&lt;/code&gt; for code example, since doc simple and easy to read and suite the need for code demonstration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/govalues/decimal"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&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;Above code would print&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;In above example has no precision loss, still since memory has a cost and not infinite, digit after the decimal point are still limited, controlling decimal digit is important, in this example you can set the size using &lt;code&gt;decimal.ParseExact()&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Storing And Retrieving
&lt;/h1&gt;

&lt;p&gt;Storing in databases also requires careful consideration to maintain precision and consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Appropriate Column Types
&lt;/h2&gt;

&lt;p&gt;Most relational databases have specific types for currency values, such as &lt;code&gt;DECIMAL&lt;/code&gt; or &lt;code&gt;NUMERIC&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid Floating-Point Storage
&lt;/h2&gt;

&lt;p&gt;Just like in programming, avoid storing currency values as floating-point numbers in databases.&lt;/p&gt;

&lt;p&gt;For example in MySQL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE `users` (
    `id` int,
    `balance` decimal(6, 2)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full MySQL Demonstration in go
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"database/sql"&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/go-sql-driver/mysql"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"root:root@tcp(127.0.0.1:3306)/test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
        CREATE TABLE test (
            id int,
            balance_decimal decimal(16, 8),
            balance_float float(16, 8),
            PRIMARY KEY (id)
        );
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INSERT INTO test (id, balance_decimal, balance_float) VALUES (1, 1.1, 1.1)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
        UPDATE test 
            SET 
                balance_decimal = balance_decimal + 1.2 , 
                balance_float   = balance_float + 1.2 
            WHERE id = 1;
    `&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;Above code would produce&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;balance_decimal&lt;/th&gt;
&lt;th&gt;balance_float&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2.30000000&lt;/td&gt;
&lt;td&gt;2.29999995&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Data Transfer
&lt;/h1&gt;

&lt;p&gt;Data transfer also requires careful consideration of precision. a correct format is required &lt;/p&gt;

&lt;p&gt;For example in JSON format, using type &lt;code&gt;string&lt;/code&gt;  guaranteed precision across any programing language&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Decimal&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"decimal"`&lt;/span&gt;
    &lt;span class="n"&gt;Float&lt;/span&gt;   &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"float"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"decimal":"999.99999999999999","float":999.99999999999999}`&lt;/span&gt;&lt;span class="p"&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;Data&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="n"&gt;_&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="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Decimal: "&lt;/span&gt;&lt;span class="p"&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;Decimal&lt;/span&gt;&lt;span class="p"&gt;)&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Float: "&lt;/span&gt;&lt;span class="p"&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;Float&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;Above code would print&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decimal: 999.99999999999999
Float: 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Handling currency in programming languages requires careful attention to detail to ensure precision, accuracy, and consistency. By using appropriate data types, libraries, and best practices, developers can avoid common pitfalls and ensure their applications handle currency correctly. Proper handling of currency not only prevents financial errors but also enhances user trust and confidence in the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There's no single best library for everyone. Each project has different needs. You should think about what's good and bad about each library based on what your project requires.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  External Link
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dikac/currency-in-go"&gt;Full Code Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;govalues/decimal Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;shopspring/decimal Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;ericlagergren/decimal Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/govalues/decimal"&gt;alpacahq/alpacadecimal Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>currency</category>
      <category>database</category>
      <category>govalues</category>
    </item>
    <item>
      <title>Handling RabbitMQ Reconnections With Go and amqp091-go</title>
      <dc:creator>dikac</dc:creator>
      <pubDate>Tue, 11 Jun 2024 09:15:42 +0000</pubDate>
      <link>https://dev.to/tentanganak/handling-rabbitmq-reconnections-with-go-and-amqp091-go-1mce</link>
      <guid>https://dev.to/tentanganak/handling-rabbitmq-reconnections-with-go-and-amqp091-go-1mce</guid>
      <description>&lt;p&gt;In a distributed system, maintaining a stable connection between components is crucial for ensuring reliable communication. This article explores strategies for reconnecting to RabbitMQ, ensuring that your applications can recover from network disruptions or broker restarts without losing valuable data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting  Up
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Importing Dependencies
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="n"&gt;amqp&lt;/span&gt; &lt;span class="s"&gt;"github.com/rabbitmq/amqp091-go"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"os/signal"&lt;/span&gt;
    &lt;span class="s"&gt;"syscall"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;amqp091-go&lt;/code&gt; as a connection for RabbitMQ&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing option
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;host&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;amqp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connection&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Channel&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;kind&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;durable&lt;/span&gt;    &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;autoDelete&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;internal&lt;/span&gt;   &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;noWait&lt;/span&gt;     &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt;       &lt;span class="n"&gt;amqp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Config&lt;/code&gt; holds connection configuration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Container&lt;/code&gt; holds the connection to RabbitMQ. In each application, they should have a wrapper for holding the connection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Channel&lt;/code&gt; holds channel configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connection Creation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// dial &lt;/span&gt;
&lt;span class="c"&gt;// create connection and register channel&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;amqp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// create connection&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amqp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"amqp://%s:%s@%s:%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq connect success"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// register channel&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExchangeDeclare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;durable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autoDelete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;noWait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq channels register success"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We create a Go function &lt;code&gt;dial&lt;/code&gt; to assist in establishing a connection to RabbitMQ. It takes in a &lt;code&gt;Config&lt;/code&gt; struct containing connection details like username, password, host, and port, and a slice of &lt;code&gt;Channel&lt;/code&gt; structs representing different channels to be registered with the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Status
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq connected: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsClosed&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;We create a Go function &lt;code&gt;check&lt;/code&gt; to check and print connection status periodically, to have visibility of the connection status.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reconnection Code
&lt;/h1&gt;

&lt;p&gt;Below is the full code containing reconnection code. We will walk through step by step to understand how reconnection works in Go with RabbitMQ.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;reconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotifyClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;amqp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&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;ok&lt;/span&gt; &lt;span class="p"&gt;{&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq connection closed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq connection closed unexpectedly, reason: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

                &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq reconnect success"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;
                &lt;span class="p"&gt;}&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq reconnect failed, err: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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;This function is a reconnect loop for a RabbitMQ client, and since reconnection creates a brand-new connection, the &lt;code&gt;reconnect&lt;/code&gt; function is required to have all the values like the initial connection.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It starts a goroutine to prevent blocking that listens for the closure of the connection.&lt;/li&gt;
&lt;li&gt;When the connection is closed, it enters a loop to attempt reconnection.&lt;/li&gt;
&lt;li&gt;It uses a delay of 1 second (&lt;code&gt;time.Sleep(time.Duration(1) * time.Second)&lt;/code&gt;) between reconnection attempts.&lt;/li&gt;
&lt;li&gt;It attempts to reconnect by calling the &lt;code&gt;dial&lt;/code&gt; function with the provided configuration and channels.&lt;/li&gt;
&lt;li&gt;If the reconnection is successful, it updates the &lt;code&gt;container.connection&lt;/code&gt; with the new connection.&lt;/li&gt;
&lt;li&gt;If the reconnection fails, it logs the error and continues the loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Stitching Together
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"guest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"guest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="m"&gt;5672&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;channels&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"reconnection-exchange"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"direct"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;durable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;autoDelete&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;noWait&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="no"&gt;nil&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="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&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;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&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;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rabbitmq connection closed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;reconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;quit&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Interrupt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SIGTERM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;quit&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;Now we combine all code together in &lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Running
&lt;/h2&gt;

&lt;p&gt;Before running the code, make sure RabbitMQ is running and accessible. Upon running the code, you should see a message like the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rabbitmq connect success
rabbitmq channels register success
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This message indicates that the RabbitMQ connection is connected normally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disconnection &amp;amp; Down
&lt;/h2&gt;

&lt;p&gt;After running and connected normally, you can emulate disconnection &amp;amp; server down by manually shutting down the RabbitMQ server. After the server stops, you should see a message like the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rabbitmq connection closed unexpectedly, reason: Exception (320) Reason: "CONNECTION_FORCED - broker forced connection closure with reason 'shutdown'"
rabbitmq connected: false
rabbitmq connected: false
rabbitmq connected: false
rabbitmq connected: false
rabbitmq reconnect failed, err: dial tcp [::1]:5672: connectex: No connection could be made because the target machine actively refused it.
rabbitmq connected: false
rabbitmq connected: false
rabbitmq connected: false
rabbitmq reconnect failed, err: dial tcp [::1]:5672: connectex: No connection could be made because the target machine actively refused it.
rabbitmq connected: false
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This message indicates disconnection from the RabbitMQ connection, and you should set up an alert for this event. &lt;/p&gt;

&lt;h2&gt;
  
  
  Reconnection
&lt;/h2&gt;

&lt;p&gt;After disconnection, you can emulate reconnection by running the RabbitMQ server again. After the server is up and ready, and the reconnection mechanism is successful, you should see a message like the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rabbitmq connect success
rabbitmq channels register success
rabbitmq reconnect success
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
rabbitmq connected: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In conclusion, the article demonstrates a robust strategy for handling RabbitMQ reconnections in Go, ensuring reliable communication in distributed systems. By implementing a reconnection loop and monitoring the connection status, the application can gracefully recover from network disruptions or broker restarts. This approach enhances the resilience of the system, ensuring that important data is not lost due to temporary connection issues. Using the amqp091-go library, developers can easily implement these reconnection mechanisms, improving the overall reliability of their RabbitMQ-based applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  External Link
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dikac/go-rabbitmq-reconnect"&gt;Full Code Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rabbitmq/amqp091-go"&gt;amqp091-go Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How To Solve Merge Conflict With Intermediate Branch</title>
      <dc:creator>dikac</dc:creator>
      <pubDate>Thu, 18 Apr 2024 07:22:36 +0000</pubDate>
      <link>https://dev.to/tentanganak/how-to-solve-merge-conflict-with-intermediate-branch-4e1n</link>
      <guid>https://dev.to/tentanganak/how-to-solve-merge-conflict-with-intermediate-branch-4e1n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Usually, in a company, there are several developers, repositories, and branches. The more features that are developed, the more complex Git branching becomes, so there needs to be a correct Git branching mechanism to make the process of merging code easier.&lt;/p&gt;

&lt;p&gt;This will explain git method to prevent tainting &lt;strong&gt;branch&lt;/strong&gt; from other &lt;strong&gt;branch&lt;/strong&gt; changes, making &lt;strong&gt;branch&lt;/strong&gt; clean and can be directly merged to &lt;strong&gt;master&lt;/strong&gt; branch, avoiding cherry-pick and reduce Merge Complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowledge Requirement
&lt;/h3&gt;

&lt;p&gt;This document assume that you have basic knowledge of git commit, merge, branch, and merge conflict.&lt;/p&gt;

&lt;p&gt;Here some basic tutorial link:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learngitbranching.js.org/" rel="noopener noreferrer"&gt;https://learngitbranching.js.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-school.github.io/visualizing-git/" rel="noopener noreferrer"&gt;https://git-school.github.io/visualizing-git/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Learning-Git-Hands-Visual-Basics/dp/1098133919/" rel="noopener noreferrer"&gt;https://www.amazon.com/Learning-Git-Hands-Visual-Basics/dp/1098133919/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;The issue came up when two or more people were working on the same shared branches like &lt;strong&gt;master&lt;/strong&gt; (for the production server) and &lt;strong&gt;staging/dev&lt;/strong&gt; (for the testing server), and pushing changes directly to these branches was not allowed.&lt;/p&gt;

&lt;p&gt;This create a situation where &lt;strong&gt;staging/dev&lt;/strong&gt; contain changes from other people and might not yet stable, thus cannot be merged to &lt;strong&gt;master&lt;/strong&gt;, and to your &lt;strong&gt;branch&lt;/strong&gt; because your &lt;strong&gt;branch&lt;/strong&gt; eventually will be merged to &lt;strong&gt;branch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
you checkout from &lt;strong&gt;master&lt;/strong&gt; to develop new functionality to &lt;strong&gt;calendar&lt;/strong&gt; feature, after finishing the development &lt;strong&gt;you&lt;/strong&gt; PR to &lt;strong&gt;staging&lt;/strong&gt;, but at the same time &lt;strong&gt;Steve&lt;/strong&gt; (other developer) working on &lt;strong&gt;calendar&lt;/strong&gt; feature to improve performance, and both &lt;strong&gt;Steve&lt;/strong&gt; and &lt;strong&gt;you&lt;/strong&gt; happen to change the same file. Now &lt;strong&gt;Steve&lt;/strong&gt; or &lt;strong&gt;You&lt;/strong&gt; cannot directly merge/rebase into &lt;strong&gt;staging&lt;/strong&gt;, now imagine if there is more than 2 developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example No Conflict
&lt;/h2&gt;

&lt;p&gt;If the &lt;strong&gt;branch&lt;/strong&gt; does not conflict with &lt;strong&gt;staging/dev&lt;/strong&gt; on PR &lt;strong&gt;You&lt;/strong&gt; don't need to use special strategy, &lt;strong&gt;You&lt;/strong&gt; can directly PR to &lt;strong&gt;main&lt;/strong&gt; &amp;amp; &lt;strong&gt;staging/dev&lt;/strong&gt; without any conflict.&lt;/p&gt;

&lt;p&gt;This happens if changes happen in different file, and if up-to branch date is not enforced.&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%2Fk2s00hdfhdioxdqpcx9z.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%2Fk2s00hdfhdioxdqpcx9z.png" alt="No Conflict"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Branch&lt;/strong&gt; created from &lt;strong&gt;master&lt;/strong&gt;, after &lt;strong&gt;branch&lt;/strong&gt; updated, PR has no merge conflict with &lt;strong&gt;master/dev&lt;/strong&gt; and &lt;strong&gt;staging/dev&lt;/strong&gt;, therefore &lt;strong&gt;intermediate branch&lt;/strong&gt; can be skipped.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;If the &lt;strong&gt;Branch&lt;/strong&gt; PR has merge conflict &lt;strong&gt;staging/dev&lt;/strong&gt;, you cannot proceed the merge, &lt;strong&gt;merging/rebase&lt;/strong&gt; from &lt;strong&gt;staging/dev&lt;/strong&gt; to &lt;strong&gt;Branch&lt;/strong&gt; will make &lt;strong&gt;Branch&lt;/strong&gt; contain changes from &lt;strong&gt;staging/dev&lt;/strong&gt; that may not stable/final yet&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%2Fb7xvrjdmzq7am4wtbq4f.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%2Fb7xvrjdmzq7am4wtbq4f.png" alt="Concept"&gt;&lt;/a&gt;&lt;em&gt;&lt;strong&gt;Branch&lt;/strong&gt; created from &lt;strong&gt;master&lt;/strong&gt;, after &lt;strong&gt;branch&lt;/strong&gt; updated, PR has merge conflict with &lt;strong&gt;staging/dev&lt;/strong&gt;, therefore &lt;strong&gt;intermediate branch&lt;/strong&gt; is needed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you &lt;strong&gt;merging/rebase&lt;/strong&gt; from &lt;strong&gt;staging/dev&lt;/strong&gt; to &lt;strong&gt;Branch&lt;/strong&gt;, then you cannot directly merge &lt;strong&gt;Branch&lt;/strong&gt; to &lt;strong&gt;Master&lt;/strong&gt; because &lt;strong&gt;Branch&lt;/strong&gt; contain changes from &lt;strong&gt;staging/dev&lt;/strong&gt; that may not stable/final.&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%2Flfkb5trczgtkkqywl8et.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%2Flfkb5trczgtkkqywl8et.png" alt="resolving merge"&gt;&lt;/a&gt;&lt;em&gt;&lt;strong&gt;Branch&lt;/strong&gt; created from &lt;strong&gt;master&lt;/strong&gt;, after &lt;strong&gt;branch&lt;/strong&gt; updated, PR has merge conflict with &lt;strong&gt;staging/dev&lt;/strong&gt;, merging &lt;strong&gt;staging/dev&lt;/strong&gt; to &lt;strong&gt;Branch&lt;/strong&gt; cause &lt;strong&gt;Branch&lt;/strong&gt; contain changes &lt;strong&gt;staging/dev&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;One solution is using new &lt;strong&gt;Intermediate branch&lt;/strong&gt; to contain &lt;strong&gt;merge conflict resolution&lt;/strong&gt; between &lt;strong&gt;branch&lt;/strong&gt; and &lt;strong&gt;staging/dev&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intermediate branch&lt;/strong&gt; accept changes from &lt;strong&gt;Branch&lt;/strong&gt; or &lt;strong&gt;staging/dev&lt;/strong&gt;, but not pushing changes to &lt;strong&gt;Branch&lt;/strong&gt;, and PR to &lt;strong&gt;Staging/Dev&lt;/strong&gt; using &lt;strong&gt;Intermediate Branch&lt;/strong&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%2F8fsogdmm73drxh8xjzq7.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%2F8fsogdmm73drxh8xjzq7.png" alt="Intermediate Branch"&gt;&lt;/a&gt;&lt;em&gt;&lt;strong&gt;Branch&lt;/strong&gt; created from &lt;strong&gt;master&lt;/strong&gt;, after &lt;strong&gt;branch&lt;/strong&gt; updated, PR has merge conflict with &lt;strong&gt;staging/dev&lt;/strong&gt;, create &lt;strong&gt;intermediate branch&lt;/strong&gt; from &lt;strong&gt;Branch&lt;/strong&gt;, merging &lt;strong&gt;staging/dev&lt;/strong&gt; to &lt;strong&gt;intermediate branch&lt;/strong&gt; will not change &lt;strong&gt;Branch&lt;/strong&gt;, &lt;strong&gt;Branch&lt;/strong&gt; are clean and can directly PR to &lt;strong&gt;Master&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now with &lt;strong&gt;intermediate branch&lt;/strong&gt;, &lt;strong&gt;Branch&lt;/strong&gt; does not contain changes from &lt;strong&gt;staging/dev&lt;/strong&gt;, and &lt;strong&gt;branch&lt;/strong&gt; is clean and can be directly PR to &lt;strong&gt;master&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now each developers &lt;strong&gt;Branch&lt;/strong&gt; does not contain changes from other developer &lt;strong&gt;Branch&lt;/strong&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%2Fndx7gjfww8yoed6qt66d.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%2Fndx7gjfww8yoed6qt66d.png" alt="Git visualized"&gt;&lt;/a&gt;&lt;em&gt;Each developers &lt;strong&gt;Branch&lt;/strong&gt; are clean and can directly PR to &lt;strong&gt;Master&lt;/strong&gt;&lt;/em&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%2Fkl7ixi4p2fc0sw8a3eq8.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%2Fkl7ixi4p2fc0sw8a3eq8.png" alt="Git workflow visualized"&gt;&lt;/a&gt;&lt;em&gt;Git workflow visualized&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Branch&lt;/strong&gt; clean can be directly PR to &lt;strong&gt;master&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No cherry picking&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Increase branch number&lt;/li&gt;
&lt;li&gt;In rare case you need to resolve the same conflict multiple times&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;By using &lt;strong&gt;intermediate branch&lt;/strong&gt; able to make &lt;strong&gt;master&lt;/strong&gt;/&lt;strong&gt;branch&lt;/strong&gt; clean in our use case. There is many branching model for git, this model works particularly well in our use case. You should also explore another branching model/strategy option, to make inform decision to decide which is best for your use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legend
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;--&amp;gt; = merge/rebase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branch&lt;/strong&gt; = Working branch outside &lt;strong&gt;master&lt;/strong&gt;, &lt;strong&gt;staging/dev&lt;/strong&gt; for feature, hotfix or anything.&lt;/li&gt;
&lt;li&gt; ⚪ = Commit&lt;/li&gt;
&lt;/ul&gt;

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