<?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: Aleksandr Korolev</title>
    <description>The latest articles on DEV Community by Aleksandr Korolev (@kunashir).</description>
    <link>https://dev.to/kunashir</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%2F632634%2Fbc5371ba-f066-430f-ae1b-5f828a2c35e2.png</url>
      <title>DEV Community: Aleksandr Korolev</title>
      <link>https://dev.to/kunashir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kunashir"/>
    <language>en</language>
    <item>
      <title>Ruby: Pass-by-Reference-Value</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Fri, 26 Dec 2025 09:33:46 +0000</pubDate>
      <link>https://dev.to/kunashir/ruby-pass-by-reference-value-2h38</link>
      <guid>https://dev.to/kunashir/ruby-pass-by-reference-value-2h38</guid>
      <description>&lt;p&gt;Most Ruby developers are likely familiar with 'Pass-by-Reference-Value'. And if you see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;var1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;
&lt;span class="n"&gt;var2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;var1&lt;/span&gt;
&lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;var1&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; Hello, Ruby&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can easily figure out what's going on.&lt;br&gt;
But how about a more complex example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DummyClass&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:value&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;dummy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DummyClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Before service action:"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceClass&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform_action&lt;/span&gt;
    &lt;span class="n"&gt;local_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@value&lt;/span&gt;
    &lt;span class="n"&gt;local_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ServiceClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform_action&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"After service action:"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; Hello, Ruby!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this particular example, it's still quite clear, especially after the first example. But it might be a totally different situation when you work on a real project.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real-World Trap
&lt;/h3&gt;

&lt;p&gt;While the behavior is clear in a small snippet, it becomes a stealthy bug in a production environment. I recently encountered this while working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an ActiveRecord model with a string attribute;&lt;/li&gt;
&lt;li&gt;a service for interpolation strings;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to replace placeholders (e.g., %%BRAND%%) within a template string. The implementation looked something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Interpolator.custom_interpolate(source, brand_name)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Semantically, a method named interpolate suggests it returns a new string. However, because the service used a mutating method (like gsub!) on the source object, it accidentally updated the ActiveRecord model's attribute in memory before the model was even saved.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Takeaway
&lt;/h3&gt;

&lt;p&gt;Even if you understand Ruby's object model, it is incredibly easy to overlook side effects when passing objects through multiple layers of abstraction. When in doubt, use non-mutating methods or explicitly .dup your inputs to ensure your "read-only" data stays that way.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>You stub/mock incorrectly</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Mon, 13 May 2024 15:47:26 +0000</pubDate>
      <link>https://dev.to/kunashir/you-stubmock-incorrectly-4076</link>
      <guid>https://dev.to/kunashir/you-stubmock-incorrectly-4076</guid>
      <description>&lt;p&gt;No one needs to read again about why tests are important and we use tests in all languages and frameworks. And you've probably faced the need to mock some calls or objects during testing.&lt;br&gt;
But firstly, let's refresh our knowledge about these ideas:&lt;br&gt;
&lt;strong&gt;mock objects&lt;/strong&gt; are simulated objects that mimic the behavior of real objects in controlled ways, most often as part of a software testing initiative (from Wikipedia).&lt;/p&gt;

&lt;p&gt;In Ruby, we have some utilities that provide abilities to mock anything that you need to mock easily. I will use &lt;code&gt;Rspec&lt;/code&gt; for my example.&lt;/p&gt;

&lt;p&gt;Just imagine that we have the next code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Survey&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;
      &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
    &lt;span class="vi"&gt;@client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;
    &lt;span class="vi"&gt;@client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we need to test this class, the straightforward approach can be next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"./survey"&lt;/span&gt;

&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Survey&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"publish survey"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"client"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:publish&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Survey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;client: &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Looks good, the test passes, but what if we change the method for Survey::Client from &lt;code&gt;publish&lt;/code&gt; to &lt;code&gt;boom&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;boom&lt;/span&gt;
      &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what will happen?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; rspec ./survey_spec.rb 
.

Finished in 0.01933 seconds (files took 0.30562 seconds to load)
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it passed, how can it be? The answer is - &lt;code&gt;double&lt;/code&gt;.&lt;br&gt;
How can we fix the problem???&lt;/p&gt;
&lt;h3&gt;
  
  
  Solution 1 (old school)
&lt;/h3&gt;

&lt;p&gt;What I don't like in languages like Ruby is all objects are quite wage and you need some mental energy to keep track of what really happens in your code. What does &lt;code&gt;Survey&lt;/code&gt; expect as an input parameter? Survey::Client? It's easy to think like this but in reality, it accepts any object with a specific interface. So what we send as a parameter to Survey should play a role. Thus in order to avoid this problem we need to check if our client can play this role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# add a shared example&lt;/span&gt;
&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shared_examples&lt;/span&gt; &lt;span class="s2"&gt;"PublisherRole"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"should response to publish"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:publish&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# add test for our client&lt;/span&gt;

&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Survey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Survey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;include_examples&lt;/span&gt; &lt;span class="s2"&gt;"PublisherRole"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and now we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rspec survey_spec.rb 
.F.

Failures:

  1&lt;span class="o"&gt;)&lt;/span&gt; Survey::Client should response to publish
     Failure/Error: DEFAULT_FAILURE_NOTIFIER &lt;span class="o"&gt;=&lt;/span&gt; lambda &lt;span class="o"&gt;{&lt;/span&gt; |failure, _opts| raise failure &lt;span class="o"&gt;}&lt;/span&gt;

       expected &lt;span class="nb"&gt;true
            &lt;/span&gt;got &lt;span class="nb"&gt;false
     &lt;/span&gt;Shared Example Group: &lt;span class="s2"&gt;"PublisherRole"&lt;/span&gt; called from ./survey_spec.rb:17
     &lt;span class="c"&gt;# ./publisher_role.rb:3:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.05281 seconds &lt;span class="o"&gt;(&lt;/span&gt;files took 0.34183 seconds to load&lt;span class="o"&gt;)&lt;/span&gt;
3 examples, 1 failure

Failed examples:

rspec ./survey_spec.rb:15 &lt;span class="c"&gt;# Survey::Client should response to publish&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution 2 (use RSpec specifics)
&lt;/h3&gt;

&lt;p&gt;What allows you to achieve the same result with less code? - &lt;code&gt;instance_double&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Survey&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"publish survey"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# use instance_double instead of double&lt;/span&gt;
    &lt;span class="c1"&gt;# client = double("client")&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;instance_double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Survey::Client"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;publish: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:publish&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Survey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;client: &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The main idea of my post is - to be aware of what you have and how you test it. Try to think maybe in one level up, not just test direct calls and objects.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
      <category>mock</category>
    </item>
    <item>
      <title>AWS Lambda + Athena + RDS</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Wed, 21 Feb 2024 16:26:19 +0000</pubDate>
      <link>https://dev.to/kunashir/aws-lambda-athena-rds-1p3e</link>
      <guid>https://dev.to/kunashir/aws-lambda-athena-rds-1p3e</guid>
      <description>&lt;p&gt;I suppose that it is not a secret now that Serverless is quite popular nowadays. I still prefer to use a more old-school approach with the classic applications (in my case Rails apps) but it turned out quite convenient in some cases.&lt;/p&gt;

&lt;p&gt;So what was the task: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;write the Lambda that should read data from the Athema table and check and do some stuff.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you create a lambda by default it has very limited permissions. If you want your lambda to make requests to Athena tables you need to add next permissions:&lt;br&gt;
   &lt;code&gt;- "athena:StartQueryExecution"&lt;br&gt;
     - "athena:GetQueryExecution"&lt;br&gt;
     - "athena:GetQueryResults"&lt;br&gt;
     - "athena:GetDataCatalog"&lt;/code&gt;&lt;br&gt;
that allows a lambda call athens APIs, but probably you will need to add more: permissions for S3 and in some cases for Glue.&lt;br&gt;
But if you have datacatalog that reflects any RDS tables you have to add special permission:&lt;br&gt;
&lt;code&gt;- "lambda:InvokeFunction"&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
because access to RDS tables happens via a special lambda connector. Unfortunately, the error message doesn't explicitly say about it, requests just fail if a lambda doesn't have this permission.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rails: has_many relationships by two columns</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Tue, 29 Aug 2023 09:53:38 +0000</pubDate>
      <link>https://dev.to/kunashir/rails-hasmany-relationships-by-two-columns-48kg</link>
      <guid>https://dev.to/kunashir/rails-hasmany-relationships-by-two-columns-48kg</guid>
      <description>&lt;p&gt;You probably use &lt;code&gt;has_many&lt;/code&gt; relationships very often. This stuff is very useful and helps to reflect a lot of relationships from the real world. For example, a car has many parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:parts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On database level, the Parts table should have a link to the Car table, usually some sort of foreign key ( car_id column in the Parts table).&lt;/p&gt;

&lt;p&gt;But what if you need to create a &lt;code&gt;has_many&lt;/code&gt; relationship by two columns?&lt;/p&gt;

&lt;p&gt;Let's imagine that we have next: except Car, there are next models:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Inventory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="c1"&gt;# it stores all possible parts that we can use for your cars&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CarInventory&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="c1"&gt;# join model&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:car&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:inventory&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Analogs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:car&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:inventory&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:inventories&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our task is to be able to get all analogs for a specific detail.&lt;br&gt;
The simplest way is just to add a link to the &lt;code&gt;CarInventory&lt;/code&gt; in &lt;code&gt;Analog&lt;/code&gt; model - create a database migration and probably data migration).&lt;br&gt;
But we use pure SQL we can fetch required data without any changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Analogs&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;CarInventory&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inventory_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inventory_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;car_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;car_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;car&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;car_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inventory_id&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;inv_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;car_inventory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to achieve this we can write the next code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# in CarInventory model&lt;/span&gt;
&lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:analogs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car_inventory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Analog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;car: &lt;/span&gt;&lt;span class="n"&gt;car_inventory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inventory: &lt;/span&gt;&lt;span class="n"&gt;car_inventory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;through: :Inventory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example probably doesn't reflect real life but I hope can reveal the idea.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Breaking interfaces</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Tue, 18 Jul 2023 08:12:47 +0000</pubDate>
      <link>https://dev.to/kunashir/breaking-interfaces-8oj</link>
      <guid>https://dev.to/kunashir/breaking-interfaces-8oj</guid>
      <description>&lt;p&gt;Let's imagine that we have two apps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;App A - a server or a data source - this app should initiate the process.&lt;/li&gt;
&lt;li&gt;App B - a client or service - this app serves the specific aim.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Initially, App A sends some data to App B (just HTTP request) and App B then sent a request to App A in order to get additional info that App B needed for the process of the request from App A. It sounds like it was too chatty and it was it.&lt;/p&gt;

&lt;p&gt;Once upon a time, we decided to fix this communication approach in a way where App A will send all required info in the first request and App B will not need to request any additional info. Sounds reasonable, doesn't it?&lt;/p&gt;

&lt;p&gt;Here, one problem pops up in our heads - backward compatibility. Because both apps are under our control, we decided that we can make breaking changes and not support both implementations at the same time. It sounded doable - proper testing, sync deployment, not a big deal... &lt;/p&gt;

&lt;p&gt;The day of deployment had come and we executed your plan. Test on production - works fine, all sides are happy.&lt;/p&gt;

&lt;p&gt;But in 2 days our operation team reported that something was wrong with data acquisition. Here I have to add some technical details: App B generates an HTML page that has a link to React app, and this page goes to the advertising network (a tag in the DSP world). The React app also was changed because the interface and corresponding data structure were change. Thus tags that are live had links to the updated React app but this new version cannot work with old data structure.&lt;/p&gt;

&lt;p&gt;We had to roll back changes for React app and use an explicit version in the new implementation.&lt;/p&gt;

&lt;p&gt;What is your approach in such a situation? Do you support old versions of interfaces or small "fire" can be acceptable?     &lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Tools: quickly connect to pods in your Kubernetes cluster</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Wed, 18 Jan 2023 15:43:23 +0000</pubDate>
      <link>https://dev.to/kunashir/tools-quickly-connect-to-pods-in-your-kubernetes-cluster-3i6a</link>
      <guid>https://dev.to/kunashir/tools-quickly-connect-to-pods-in-your-kubernetes-cluster-3i6a</guid>
      <description>&lt;p&gt;It seems that almost all companies use or try to use Kubernetes. And you, as a developer, need from time to time connect to your app, but when it is in a Kubernetes cluster, it is not so simple.&lt;br&gt;
How it can look like in your case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# switch to appropriate context &lt;/span&gt;
kubectl ctx your-context
&lt;span class="c"&gt;# get pods&lt;/span&gt;
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; namespace get pods
&lt;span class="c"&gt;# connect to the pod&lt;/span&gt;
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; nameapce &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; pod/#&lt;span class="o"&gt;{&lt;/span&gt;pod-name-from-previous-step&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; bash 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do it every time - tedious, isn't it?&lt;br&gt;
In my team, we are using next script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# how make script executable&lt;/span&gt;

&lt;span class="c"&gt;# chmod +x k8s.sh&lt;/span&gt;

&lt;span class="c"&gt;# this is necessary to split the command output on new lines&lt;/span&gt;

&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'

'&lt;/span&gt;

show_help &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: k8s.sh [environment] [SUBENV] - ssh to a pod from the environment-subenv"&lt;/span&gt;

  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Example: k8s.sh staging web - connect to the web pod in the staging environment"&lt;/span&gt;

  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"It uses current directory in order to build the pod name"&lt;/span&gt;

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




&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-h"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"--help"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then

  &lt;/span&gt;show_help

  &lt;span class="nb"&gt;exit &lt;/span&gt;1

&lt;span class="k"&gt;fi




&lt;/span&gt;&lt;span class="nv"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

&lt;span class="nv"&gt;SUBENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;




&lt;span class="nv"&gt;working_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="p"&gt;##*/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$working_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'[:upper:]'&lt;/span&gt; &lt;span class="s1"&gt;'[:lower:]'&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$project&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;$ENVIRONMENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;




kubectl ctx |  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENVIRONMENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt;  | xargs &lt;span class="nt"&gt;-0&lt;/span&gt; kubectl ctx




&lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$namespace&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; get pods | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SUBENV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | Head &lt;span class="nt"&gt;-n&lt;/span&gt; 1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;podname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="p"&gt;%% *&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;#* &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;




&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ing you into &lt;/span&gt;&lt;span class="nv"&gt;$podname&lt;/span&gt;&lt;span class="s2"&gt; . . ."&lt;/span&gt;




kubectl &lt;span class="nt"&gt;--namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;namespace&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; pod/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;podname&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It allows easily connect to pods from a specific namespace (a namespace depends on current directory - current project).&lt;br&gt;
Subenv is necessary because we have different types of pods (web, activejobs, migration).&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>bash</category>
    </item>
    <item>
      <title>Don't like long, verbose Docker-compose command?</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Tue, 22 Mar 2022 08:08:56 +0000</pubDate>
      <link>https://dev.to/kunashir/dont-like-long-verbose-docker-compose-command-239m</link>
      <guid>https://dev.to/kunashir/dont-like-long-verbose-docker-compose-command-239m</guid>
      <description>&lt;p&gt;Nowadays many developers and companies use Docker and Docker-compose in everyday live. I don't want to repeat what Docker is and why you might want to use it. But what I don't like when I work with Docker (if be more precisely with Docker-compose) - verbosity of commands.&lt;/p&gt;

&lt;p&gt;It is hard to argue that Docker-compose provide good alternative compare with pure Docker interface but commands are still long and verbose. "It is not a problem" - you could reply, - "just add appropriate alias for the command and save time and effort". Yes, right, it can help in terminal but you are as a developer probably use IDE or at least text editor and often you have mechanisms for interact with your application somehow: run test, initialise building process etc. And not all IDEs and text-editors know how work with Docker.&lt;/p&gt;

&lt;p&gt;From my point of view, the ideal setup is when you don't need to think about if you use Docker or not. For example, I need to run my tests with &lt;code&gt;rspec&lt;/code&gt; (I'm a Rails-developers and all examples below are from Rails world), it would be great not to think about what should I do in order to run them - my habit is &lt;code&gt;rspec path/to/specs&lt;/code&gt; but when my app is in Docker I should do something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose run -rm container-name command&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And in this case this &lt;a href="https://github.com/bibendi/dip" rel="noopener noreferrer"&gt;utility&lt;/a&gt; can safe us.&lt;br&gt;
DIP has two possible modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;dip your_command&lt;/code&gt; - in this mode you just need to type &lt;code&gt;dip&lt;/code&gt; before your command, something like this: &lt;code&gt;dip rails c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;your_command&lt;/code&gt; - DIP can be injected into the current shell and it analyses current directory if there is an dip.yml file, if the file is exist it runs a command in docker if not in a shell.
But before this sunny live you need to create &lt;code&gt;dip.yml&lt;/code&gt; - a configuration file when you should make mapping specific commands to appropriate container.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Possible pitfalls:&lt;br&gt;
I use &lt;code&gt;vim&lt;/code&gt; for development and by default &lt;code&gt;vim&lt;/code&gt; didn't use &lt;code&gt;dip&lt;/code&gt; when I tried to run command from &lt;code&gt;vim&lt;/code&gt;. The problem was in an approach which &lt;code&gt;vim&lt;/code&gt; uses when run external command - it doesn't load your shell's profile by default. In order to force it I've added next to my &lt;code&gt;.vimrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;set shell=bash\ -l&lt;br&gt;
&lt;/code&gt; &lt;/p&gt;

</description>
      <category>docker</category>
      <category>dockercompose</category>
    </item>
    <item>
      <title>Rails design pattern</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Thu, 18 Nov 2021 10:13:40 +0000</pubDate>
      <link>https://dev.to/kunashir/rails-design-pattern-1c7e</link>
      <guid>https://dev.to/kunashir/rails-design-pattern-1c7e</guid>
      <description>&lt;p&gt;If you are a Rails-developer you know at least MVC pattern. Most of us know of course that it has some limitations in terms of structuring your code (fat controllers/models) and in some point of your developer's path you start thinking about code quality and here I mean not code style and other minor things but more general - single responsibility principal (SRP) and how we can organize code in order to make it real, Liskov’s Substitution Principle etc.&lt;/p&gt;

&lt;p&gt;Ok, we have spotted a problem and what can we do with it?&lt;br&gt;
As you can have noticed - SOLID principles and general OO design are our tools. But they are too general. Are there something more specific? Googling will provide you at least next possible patterns: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builder&lt;/li&gt;
&lt;li&gt;Decorator&lt;/li&gt;
&lt;li&gt;Form&lt;/li&gt;
&lt;li&gt;Interactor&lt;/li&gt;
&lt;li&gt;Observer&lt;/li&gt;
&lt;li&gt;Policy&lt;/li&gt;
&lt;li&gt;Presenter&lt;/li&gt;
&lt;li&gt;Query&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;li&gt;Value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am not going to retell them, you can easily find definitions. But I want to light on next moment: how many from them you are using in yours projects? Is it straightforward which pattern you need to use?&lt;/p&gt;

&lt;p&gt;Let take for example Service and Interactor:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;em&gt;service&lt;/em&gt; design pattern breaks down a program into its functional constituents. Each service object completes one task, such as running payment for a customer, completing a bank transaction, etc.&lt;/p&gt;

&lt;p&gt;You can use the &lt;em&gt;interactor&lt;/em&gt; design pattern to split a large task into a series of small, inter-dependent steps. If any of the steps fail, the flow stops, and a relevant message appears about why the execution failed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The definitions are different but the aim is the same - breaks down something big into small blocks. From my point of view, the interactor pattern is a special case of service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticateUser&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Interactor&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;secret_token&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fail!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"authenticate_user.failure"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This excerpt was written in context of &lt;em&gt;interactor&lt;/em&gt; gem.&lt;br&gt;
and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticateUserService&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseService&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;success_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# this method as and error_result are implemented in BaseService&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;error_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does it look similar? From my perspective, they are not different patterns but one pattern with slightly different implementation.  &lt;/p&gt;

&lt;p&gt;Let's take anther one confusing couple: &lt;em&gt;Decorator&lt;/em&gt; vs &lt;em&gt;Presenter&lt;/em&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Decorator pattern adds new functionality to an existing object by wrapping it with additional objects containing the new features. This helps to modify an instance of a class for extra features and not define new static subclasses in the code.&lt;/p&gt;

&lt;p&gt;The Presenter design pattern aims to isolate view rendering logic from the controller and model and encapsulate it into a reusable component. It makes the controller and models leaner and enhances code readability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a look into code snippets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostPresenter&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;image&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'no-image.png'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# similary define other methods with their logic&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roof&lt;/span&gt;
    &lt;span class="s2"&gt;"fixed"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConvertibleDecorator&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;SimpleDelegator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roof&lt;/span&gt;
    &lt;span class="s2"&gt;"collapsible"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decorate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

 &lt;span class="kp"&gt;private&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;model&lt;/span&gt;
   &lt;span class="n"&gt;__getobj__&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;#using &lt;/span&gt;
&lt;span class="n"&gt;basicCar1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;basicCar2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;basicCar1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ConvertibleDecorator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decorate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicCar1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicCar1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; collapsible&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicCar2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; fixed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can argue that is different approach... but I would like to say - different implementation but the aim is the same. Both examples are trying to separate some additional(auxiliary) logic in separate place. And there are other way for do it, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roof&lt;/span&gt;
    &lt;span class="s2"&gt;"fixed"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ConvertibleDecorator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roof&lt;/span&gt;
    &lt;span class="s2"&gt;"collapsible"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;#using &lt;/span&gt;
&lt;span class="n"&gt;basicCar1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;basicCar2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;basicCar1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;basicCar1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ConvertibleDecorator&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicCar1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; collapsible&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicCar2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; fixed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some other patterns are more straightforward and not so confusing. But the main idea of the post is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;try to use general principle when you structure the code (SOLID);&lt;/li&gt;
&lt;li&gt;not use patterns because it is just the best practice but when you can see that it makes sense; if you cannot match you class with one of this patterns it is ok if you use something new what related to you problem (often developers see &lt;code&gt;Services&lt;/code&gt; in a project and try to put all new classes there however it can be QueryObject or ValueObject).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The definitions of the patterns and part of examples were taken from &lt;a href="https://scoutapm.com/blog/rails-design-patterns#h_61620597268511623876237034" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>programming</category>
    </item>
    <item>
      <title>MySql: Shrink DB partially</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Tue, 25 May 2021 13:10:54 +0000</pubDate>
      <link>https://dev.to/kunashir/mysql-shrink-db-partially-2gm1</link>
      <guid>https://dev.to/kunashir/mysql-shrink-db-partially-2gm1</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;We have a Rails application and with time some tables in our Database (DB) became too big. For example, one of them is 2.7Tb, another one which is in use with high frequency has a size 5.5Tb. This fact with some not optimal structure of DB brought us problems with operating data. We had implemented the process for deleting old data from the DB but when it runs it is impossible to do everyday work with data — the application is struggling a lot.&lt;br&gt;
We had decided to cut some tables totally (if be more precisely leave just data but 3 months) and rest copy totally. The main question was how can we do it without long downtime. Even if we cut the biggest tables it would be around 500Gb.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial idea
&lt;/h2&gt;

&lt;p&gt;The difficult part of the process was partially copying data from the same tables. The simple way which goes to mind is to stop the application, delete data, run &lt;code&gt;optimize table&lt;/code&gt;. But with our size, it takes too long. So another brave idea was nominated: create a replica, initialize it only with tables which we need fully, and start replicating from scratch those which we want to reduce. “Hm… sounds cool”: thought we, the man who had met replication only in the format &lt;code&gt;press button create a new replica in AWS&lt;/code&gt;.&lt;br&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%2Fyiv0pmyha7ar5e3jskt8.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%2Fyiv0pmyha7ar5e3jskt8.png" alt="image" width="800" height="507"&gt;&lt;/a&gt;&lt;br&gt;
 So we’ve created a new instance in AWS RDS, copied the schema of the database, took Percona pt-table-sync (&lt;a href="https://www.percona.com/doc/percona-toolkit/LATEST/pt-table-sync.html" rel="noopener noreferrer"&gt;https://www.percona.com/doc/percona-toolkit/LATEST/pt-table-sync.html&lt;/a&gt;) for copying the tables which we wanted to have fully, and setup external master for replication with &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql_rds_set_external_master.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql_rds_set_external_master.html&lt;/a&gt; this function (we used this because the standard way for making replication on AWS RDS makes snapshots).&lt;br&gt;
We’d started with a staging environment and it looked like a working solution. However, Percona recommends using replication for copying data we used direct mode because &lt;code&gt;pt-table-sync&lt;/code&gt; tries to set up replication mode to &lt;code&gt;STATEMENT&lt;/code&gt; but RDS doesn’t allow it from SQL command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems
&lt;/h2&gt;

&lt;p&gt;It’s time to try the same on the production. We’ve made all the same steps, run the replication but at the same time got the replication error: 1032 HA_ERR_KEY_NOT_FOUND. Googling and reading documentation gave us the view that a table has no record which should be updated. You can say: but you’ve said that worked for staging. Yes, it worked sometimes but we didn’t pay attention to this after a long time and also environments have some differences (not all background jobs work on staging and loading much less).&lt;br&gt;
But these errors happened on tables which we wanted to reduce, thus we can ignore it — we thought. MySQL allows you to ignore any errors by simply setting a list of these errors in the config file:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;slave-skip-errors=1032,1062,1146&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cool, let’s do it. But wait, we are using RDS and don’t have the ability to change MySQL settings directly. Even more, you cannot do it through a parameters group. What AWS allows you to do is skip just one error at a time — we had thousands.&lt;br&gt;
Game is up? No! Engineers never give up we’ve made from steel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final solution
&lt;/h2&gt;

&lt;p&gt;We appreciate the care of AWS about us through limitations. If we cannot do it on RDS what if set up our own MySQL server — no problem. We’ve run a new EC2 instance, installed the MySQL — here we can do all that we want!&lt;br&gt;
So the idea was: set up a replication process to the main DB and ignore all those errors that interrupted us on the RDS instance. After 3 months of replication, we will be ready for using this database. But we don’t want to use a standalone server, we want to continue to use RDS. For this step we considered two possibilities: 1) use mysqldump and setup replication on a new RDS instance from the same point at which we make dump 2) use AWS DMS service.&lt;br&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%2Fmw1yskeb09q0p3ew78cn.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%2Fmw1yskeb09q0p3ew78cn.png" alt="image" width="700" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Look to the process more details:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup standalone MySQL server&lt;/li&gt;
&lt;li&gt;Make a clone of the source database through the process of creating a Read replica on RDS&lt;/li&gt;
&lt;li&gt;Stop replication on this replica (remember the point in binary log when replication will stop)&lt;/li&gt;
&lt;li&gt;Dump database with specific tables&lt;/li&gt;
&lt;li&gt;Load dump to the database on the standalone server.&lt;/li&gt;
&lt;li&gt;Setup the replication process from the point at which we stop it on step 3.&lt;/li&gt;
&lt;li&gt;When we have enough data to switch to the new DB — stop replication on a standalone server (also need to remember the point of the replication process).&lt;/li&gt;
&lt;li&gt;Initialize a new RDS instance with data from the standalone server.&lt;/li&gt;
&lt;li&gt;Setup replication at the same point but for the main server for catching up on new data which can be written while we load data to a new RDS instance.&lt;/li&gt;
&lt;li&gt;Switch the application to the new database.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;It is not a proper way of using replication, thus it can bring some troubles during the process. Some additional steps were involved because of the limitations of MySQL.&lt;br&gt;
But the main outcome: try to not allow DB to go in this direction when you cannot work with it smoothly. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rails find_each/ find_in_batches pitfalls</title>
      <dc:creator>Aleksandr Korolev</dc:creator>
      <pubDate>Mon, 17 May 2021 12:27:33 +0000</pubDate>
      <link>https://dev.to/kunashir/rails-findeach-findinbatches-pitfalls-148n</link>
      <guid>https://dev.to/kunashir/rails-findeach-findinbatches-pitfalls-148n</guid>
      <description>&lt;p&gt;Every rails-developer knows about method &lt;code&gt;find_each&lt;/code&gt; or &lt;code&gt;find_in_batches&lt;/code&gt; (if you check the implementation for the first one you find that it uses the second one under the hood) from &lt;strong&gt;ActiveRecord&lt;/strong&gt;. Even more, it is a good practice to use these methods when you need to iterate throw a big amount of records in DB.&lt;br&gt;
If you don't familiar with it you can check this &lt;a href="https://apidock.com/rails/ActiveRecord/Batches/find_each" rel="noopener noreferrer"&gt;https://apidock.com/rails/ActiveRecord/Batches/find_each&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looks like, we always can/must use &lt;code&gt;find_each&lt;/code&gt; instead of &lt;code&gt;each&lt;/code&gt; when we need to iterate throw some bunch of records. We also thought this way. But one of our applications struggled with DB: load for DB was around 95%, it was obvious that DB is a bottleneck.&lt;/p&gt;

&lt;p&gt;I'd started to analyze slow-query logs in MySQL and reports in NewRelic. It was quite simple to find the place in the code which produce this SQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="no"&gt;Survey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:offer_uuid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;active&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;provider: &lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;survey_id: &lt;/span&gt;&lt;span class="n"&gt;current_surveys&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find_in_batches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;batch_size: &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;survey_batch&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;DeactivateSurveysService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;survey_batch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of using &lt;code&gt;where.not&lt;/code&gt; MySQL should fetch all records in order to sort them by id (this sorting used in &lt;code&gt;find_each/find_in_batches&lt;/code&gt;) and only after this takes 10 records - it can very slow if a scope of the records is big how we had.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;CONCLUSION&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is good practice using &lt;code&gt;find_each&lt;/code&gt;/&lt;code&gt;find_in_batches&lt;/code&gt; in order to not consume a lot of memory but need to be aware of what resulting SQL is.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>activerecord</category>
    </item>
  </channel>
</rss>
