<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Hello, I am Midhun Krishna]]></title><description><![CDATA[I am a Lead Software Developer at Nuna. I have always been a tech enthusiast. When I started my career,  I got hooked into the habit of writing clean and well designed code. ]]></description><link>https://midhunkrishna.in/</link><image><url>https://midhunkrishna.in/favicon.png</url><title>Hello, I am Midhun Krishna</title><link>https://midhunkrishna.in/</link></image><generator>Ghost 3.41</generator><lastBuildDate>Thu, 09 Apr 2026 07:02:19 GMT</lastBuildDate><atom:link href="https://midhunkrishna.in/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Debugging a stuck Ruby process using gdb/lldb]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="https://midhunkrishna.in/content/images/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg" class="kg-image" alt srcset="https://midhunkrishna.in/content/images/size/w600/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 600w, https://midhunkrishna.in/content/images/size/w1000/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 1000w, https://midhunkrishna.in/content/images/size/w1600/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 1600w, https://midhunkrishna.in/content/images/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 2048w" sizes="(min-width: 720px) 720px"></figure><p></p><p>This post is a case study of an issue I faced in the form of a stuck Ruby micro-service. The Rails server would boot up and service requests for a while until it would stop responding.</p><p>The next problem was verification. How can we tell that the process is stuck?</p>]]></description><link>https://midhunkrishna.in/debugging-a-stuck-process-using-gdb-lldb/</link><guid isPermaLink="false">5f94460e0379ed43f3a7928d</guid><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Sun, 15 Nov 2020 12:47:36 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="https://midhunkrishna.in/content/images/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg" class="kg-image" alt srcset="https://midhunkrishna.in/content/images/size/w600/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 600w, https://midhunkrishna.in/content/images/size/w1000/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 1000w, https://midhunkrishna.in/content/images/size/w1600/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 1600w, https://midhunkrishna.in/content/images/2025/03/Gemini_Generated_Image_g0p642g0p642g0p6.jpeg 2048w" sizes="(min-width: 720px) 720px"></figure><p></p><p>This post is a case study of an issue I faced in the form of a stuck Ruby micro-service. The Rails server would boot up and service requests for a while until it would stop responding.</p><p>The next problem was verification. How can we tell that the process is stuck? What are the conditions that contribute to it?</p><h2 id="to-verify-that-the-process-is-indeed-stuck-">To verify that the process is indeed, stuck!</h2><p>The primary characteristic of a stuck process is that it stops responding to interrupts, save the kill signal. Puma server has a <a href="https://github.com/puma/puma/blob/master/docs/signals.md#puma-signals">well documented and robust interrupt behavior</a>.</p><p>Lets send USR1 signal to the process to see what is the default behavior of Puma.</p><pre><code class="language-text"># IN TERMINAL A

master ● bundle exec rails s
=&gt; Booting Puma
=&gt; Rails 6.0.2.2 application starting in development
=&gt; Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.3 (ruby 2.7.0-p0), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop

# IN TERMINAL B

● lsof -i tcp:3000 | tail -1 | cut -d' ' -f 5 
92187
● sudo kill -USR1 92187

# BACK IN TERMINAL A

...
* phased-restart called but not available, restarting normally.
* Restarting...
=&gt; Booting Puma
=&gt; Rails 6.0.2.2 application starting in development
=&gt; Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.3 (ruby 2.7.0-p0), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop</code></pre><p>I found that the microservice didn’t exhibit the above behaviour after sending a restart signal.  </p><h2 id="to-find-the-steps-that-lead-to-a-stuck-process-">To find the steps that lead to a stuck process.</h2><h3 id="dtrace-via-dtruss">dtrace via dtruss</h3><p>I have had much success with <strong><em>strace</em></strong> to identify the cause of a similar problem, in the past. I tried installing it on my Mac laptop and found that strace is only available on linux but, there is an alternative, dtrace via dtruss.</p><pre><code class="language-bash">sudo dtruss -p &lt;PID&gt;</code></pre><p>The above command starts a firehose of logs ( especially if the process is active ) which gives an idea the type of system calls made by the process monitored by dtruss. Unlike strace, dtrace didn't seem to slow down the process it was attached to.</p><p>This proved to be a dead end as I was not able to figure-out a pattern and decided to look for alternatives. While I was reading up on dtrace, I came across <a href="https://rhardih.io/2017/11/behind-the-scenes-of-shell-io-redirection/">Behind the scenes of shell IO redirection</a> by <a href="https://rhardih.io/author/rene/" rel="author">René Hansen</a>. This post gives a fair idea of how to use the tool and it also includes suggested reading. </p><h3 id="rbtrace">rbtrace</h3><p>I came across this <a href="https://twitter.com/samsaffron/status/445728497160294400">tweet from Sam Saffron</a> on using rbtrace for debugging stuck process and decided to give rbtrace a try. Originally written by <a href="https://github.com/tmm1">Aman Gupta</a>, who is the author of libraries such as EventMachine, rbtrace describes itself as, <strong><em>like strace, but for Ruby code. </em></strong></p><p>rbtrace has a very robust interface which allows for fine grained control over the desired output format. I started with the full verbose tracing. </p><pre><code class="language-ruby"># application.rb
require 'rbtrace'

# TERMINAL A
bundle exec rails s

# TERMINAL B
rbtrace -p 87854 --firehose</code></pre><p>Since the micro-service had many threads and did many things in the background, rbtrace's verbosity was simply, like in the case of dtrace, quite overwhelming.</p><p>I still didn't know what I was looking for, which made the whole task akin to looking for a needle in a haystack.  To give an idea of the haystack's size, for a freshly created Rails application, visiting localhost:3000 resulted over 94,000 lines of rbtrace-logs.</p><p>I also found that rbtrace was only usable as long as the primary Ruby process was responsive. Once the main process gets stuck, rbtrace stopped sending any messages, or the client refused to 'attach' to the process. This proved not useful, mostly when I ran the script shared in the tweet above.</p><p><em><strong>P.S </strong></em></p><p>In hindsight, I feel I didn't spent much time with rbtrace, as much as I did with dtruss. rbtrace is an excellent tool and if I had given enough time, I could have found the root cause without using lldb. </p><h2 id="inspecting-a-process-with-lldb-">Inspecting a process with lldb.</h2><p>I needed a tool that could show me the exact state of the process and threads after it is stuck, which led me to gdb and eventually to lldb.</p><p>Apparently, MacOs dropped support for gdb, and since 2005 Mac has been steadily moving away from the GNU toolchain. I decided to give lldb a go. <strong><em>lldb </em></strong>gets installed whenever Xcode Tools or Xcode is installed. </p><p><strong>NOTE:</strong><br>All lldb stacktraces are read bottom-up, hence frame #1 is chronologically after frame #2.</p><p>Running lldb on the stuck Ruby process, </p><pre><code class="language-bash">master ● sudo lldb -p 20722
(lldb) process attach --pid 20722
Process 20722 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10
libsystem_kernel.dylib`__psynch_cvwait:
-&gt;  0x7fff7279f882 &lt;+10&gt;: jae    0x7fff7279f88c            ; &lt;+20&gt;
    0x7fff7279f884 &lt;+12&gt;: movq   %rax, %rdi
    0x7fff7279f887 &lt;+15&gt;: jmp    0x7fff7279d629            ; cerror_nocancel
    0x7fff7279f88c &lt;+20&gt;: retq
Target 0: (ruby) stopped.

Executable module set to "/Users/&lt;user&gt;/.rbenv/versions/2.5.1/bin/ruby".
Architecture set to: x86_64h-apple-macosx-.
(lldb)</code></pre><p>Don't worry with all that stuff that is in that log/code snippet. It didn't make sense to me either.  What we are interested, are in the threads. What are the threads doing?</p><p>I could see the list of all running threads using <strong><em>thread list</em></strong> command.</p><pre><code class="language-bash">(lldb) thread list
Process 20722 stopped
* thread #1: tid = 0x8f037, 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  thread #2: tid = 0x8f039, 0x00007fff727a33d6 libsystem_kernel.dylib`poll + 10, name = 'ruby-timer-thr'
  thread #3: tid = 0x8f04a, 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'ruby_thread_lo*'
  thread #4: tid = 0x8f088, 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'connection_poo*'
  thread #5: tid = 0x8f0bf, 0x00007fff727a50fe libsystem_kernel.dylib`__select + 10, name = 'thread_pool.rb*'
  thread #6: tid = 0x8f0c0, 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'thread_pool.rb*'
 
 ...</code></pre><p>I needed a way to find out what these threads are currently doing. <strong><em>thread backtrace all </em></strong>provides backtraces of all the threads that are running. </p><pre><code class="language-bash">(lldb) thread backtrace all
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff72860425 libsystem_pthread.dylib`_pthread_cond_wait + 698
    frame #2: 0x00000001070714b3 libruby.2.5.dylib`gvl_acquire_common + 179
    frame #3: 0x0000000107068b13 libruby.2.5.dylib`native_sleep + 435
    ...
    frame #26: 0x00007fff7265bcc9 libdyld.dylib`start + 1
    
  thread #2, name = 'ruby-timer-thr'
    frame #0: 0x00007fff727a33d6 libsystem_kernel.dylib`poll + 10
    frame #1: 0x00000001052236d1 libruby.2.5.dylib`thread_timer + 417
    frame #2: 0x00007fff72860109 libsystem_pthread.dylib`_pthread_start + 148
    frame #3: 0x00007fff7285bb8b libsystem_pthread.dylib`thread_start + 15
    
  thread #3, name = 'ruby_thread_lo*'
    frame #0: 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff72860425 libsystem_pthread.dylib`_pthread_cond_wait + 698
    frame #2: 0x000000010521abaa libruby.2.5.dylib`native_sleep + 586
    frame #3: 0x0000000105225746 libruby.2.5.dylib`queue_sleep + 118
...</code></pre><p>Let's look at the backtrace of one specific thread, say the first one, and see try to figureout what it is doing. </p><figure class="kg-card kg-image-card"><img src="https://midhunkrishna.in/content/images/2020/11/ruby-gvl_acquire_common.png" class="kg-image" alt srcset="https://midhunkrishna.in/content/images/size/w600/2020/11/ruby-gvl_acquire_common.png 600w, https://midhunkrishna.in/content/images/size/w1000/2020/11/ruby-gvl_acquire_common.png 1000w, https://midhunkrishna.in/content/images/2020/11/ruby-gvl_acquire_common.png 1484w" sizes="(min-width: 720px) 720px"></figure><p><strong>(1) </strong>command to select the first thread<br><strong>(2) </strong>Shortcut <strong><em>bt </em></strong>for<strong><em> backtrace, </em></strong>shows the full backtrace of the thread.<br><strong>(3) </strong><a href="https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_cond_wait.html"><strong>_</strong><em><strong>pthread_cond_wait</strong></em></a> comes from pthread.h file of the underlying C implementation of Ruby. This function is used to conditionally wait until a mutex is released.<br><strong>(4) <em>gvl_acquire_common </em></strong>Thread is currently trying to acquire GVL as any<strong> </strong>Ruby thread that wishes to execute should acquire the GVL. </p><p>To summarize, this particular thread is trying to acquire GVL, but is conditionally waiting for a mutex to be released. </p><p>This is part of how threads are scheduled within the Ruby runtime, but in our case a majority of these threads were stuck with <em><strong>gvl_acquire_common, </strong></em>which was not normal.</p><h2 id="the-curious-ones-">The curious ones.</h2><p>Now that these threads are stuck waiting to <strong><em>acquire</em></strong> the Global Interpreter Lock, we need to find out what is causing them to wait. The best way to figure that out is to look for threads with unusual backtraces that stand-out from the rest.</p><p>Following are the list of  <a href="https://www.youtube.com/watch?v=GEPhLqwKo6g">the crazy ones, the misfits, the rebels, the troublemakers</a> out of a total of 67 threads. </p><p><strong><em>thread #2, name = 'ruby-timer-thr'</em></strong><br>The timer thread is part of thread-scheduling mechanism of Ruby language. It is a native thread and can be safely ignored from our list of suspects.  </p><figure class="kg-card kg-code-card"><pre><code class="language-bash">
thread #2, name = 'ruby-timer-thr'
    frame #0: 0x00007fff727a33d6 libsystem_kernel.dylib`poll + 10
    frame #1: 0x0000000107071763 libruby.2.5.dylib`thread_timer + 563
    frame #2: 0x00007fff72860109 libsystem_pthread.dylib`_pthread_start + 148
    frame #3: 0x00007fff7285bb8b libsystem_pthread.dylib`thread_start + 15</code></pre><figcaption>thread #2 'ruby-timer-thr'</figcaption></figure><p><br><strong><em>thread #6, name = 'utils.rb:193'</em></strong><br>If we read from frame #7 to #3 of the following backtrace, we can see that this thread is trying to get a lock on something called a <strong><em>v8::Isolate</em></strong><em>.</em> <a href="https://v8docs.nodesource.com/node-0.8/d5/dda/classv8_1_1_isolate.html#details">On further reading</a>, it looks like a <strong><em>v8::Isolate</em></strong> is an isolated instance of <strong><em>V8 engine</em></strong>, the Javascript interpreter that powers Chrome and Node.js.</p><figure class="kg-card kg-code-card"><pre><code class="language-text">thread #6, name = 'utils.rb:193'
    frame #0: 0x00007fff7279f062 libsystem_kernel.dylib`__psynch_mutexwait + 10
    frame #1: 0x00007fff7285d917 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 83
    frame #2: 0x00007fff7285b937 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 222
    frame #3: 0x0000000107c3d376 libv8.dylib`v8::Locker::Locker(v8::Isolate*) + 94
    frame #4: 0x0000000107a54976 init.bundle`rr::Locker::doLock(int, unsigned long*, unsigned long) [inlined] rr::Locker::setupLockAndCall(state=0x0000700003b9083c, code=140299575081440) at locker.cc:47:17
    frame #5: 0x0000000107a5496f init.bundle`rr::Locker::doLock(argc=&lt;unavailable&gt;, argv=0x00007f9a70448470, self=&lt;unavailable&gt;) at locker.cc:39
    frame #6: 0x00000001070b39cc libruby.2.5.dylib`vm_call_cfunc + 284
    frame #7: 0x000000010709af09 libruby.2.5.dylib`vm_exec_core + 9497
    ...</code></pre><figcaption>thread #6 'utils.rb:193'</figcaption></figure><p></p><p><strong><em>thread #8, name = 'utils.rb:193'</em></strong><br>I also found few other threads with similar backtraces, the ones with <em><strong>rb_thread_io_blocking_region (in frame #1) </strong></em>call. Reading up the backtrace from frame #6 upto #0, it looks like this thread is doing a IO operation. We also know that a Ruby thread doesn't need GVL for performing IO and hence this thread can be safely eliminated from our list of possible suspects. </p><figure class="kg-card kg-code-card"><pre><code class="language-text">thread #8, name = 'utils.rb:193'
    frame #0: 0x00007fff7279d81e libsystem_kernel.dylib`read + 10
    frame #1: 0x000000010706a769 libruby.2.5.dylib`rb_thread_io_blocking_region + 265
    frame #2: 0x0000000106f6d12d libruby.2.5.dylib`io_fillbuf + 157
    frame #3: 0x0000000106f6daba libruby.2.5.dylib`rb_io_getline_0 + 1162
    frame #4: 0x0000000106f83ee1 libruby.2.5.dylib`rb_io_getline + 113
    frame #5: 0x0000000106f7874b libruby.2.5.dylib`rb_io_gets_m + 11
    frame #6: 0x00000001070b39cc libruby.2.5.dylib`vm_call_cfunc + 284
    ...</code></pre><figcaption><strong>t</strong>hread #8 'utils.rb:193'</figcaption></figure><p></p><p><strong><em>thread #21, name = 'base.rb:118'</em></strong><br>The following thread, Thread 21 is an example of a thread that is waiting to be scheduled by the Ruby vm. As it is not doing anything, we can remove this one as well from our list. </p><figure class="kg-card kg-code-card"><pre><code class="language-text">thread #21, name = 'base.rb:118'
    frame #0: 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff72860425 libsystem_pthread.dylib`_pthread_cond_wait + 698
    frame #2: 0x0000000107068baa libruby.2.5.dylib`native_sleep + 586
    frame #3: 0x0000000107073746 libruby.2.5.dylib`queue_sleep + 118
    frame #4: 0x0000000106f45d51 libruby.2.5.dylib`rb_ensure + 193
    ...
    </code></pre><figcaption>thread #21 'base.rb:118'</figcaption></figure><p></p><p><strong><em>thread #41, name = 'utils.rb:193'</em></strong><br>This thread is doing a lot. On frame #32, it is starting a foreign function written in <em><strong>C</strong></em> via <em><strong>vm_call_cfunc</strong>. </em>Throughout the backtrace, we can see namespacing of the form <strong><em>rr::</em></strong><em>. </em>This is a namespace created by <strong><em><a href="https://github.com/rubyjs/therubyracer">therubyracer gem</a></em></strong>. ( therubyracer gem is used to evaluate Javascript strings from Ruby)</p><ul><li>Frames #32 through #30 locks the V8::Isolate. This section is very similar to the backtrace of <strong>thread #6</strong>.</li><li>Frames #29 through #21 the sets-up a <strong><em>v8::Handle</em></strong>. <a href="https://v8docs.nodesource.com/node-0.8/d3/dd5/classv8_1_1_handle.html#details">From v8's documentation</a>, here we are creating what is called a Transient Handle (There are two types of Handles, Transient and Permanent ), which is used by V8's GC to keep track of objects created, within current scope. </li><li>Frames #28 through #12 <a href="https://v8docs.nodesource.com/node-0.8/d4/dc6/classv8_1_1_try_catch.html">registers an external exception handler with the v8::Isolate</a>. </li><li>Frames #11 through #10 executes the javascript string.</li><li>Frames #9 through #0 tries to capture that result and get it back into the calling user-land Ruby thread, but as we can see, on frame #2, it gets stuck on <strong><em>gvl_acquire_common</em></strong>.</li></ul><figure class="kg-card kg-code-card"><pre><code class="language-text">thread #41, name = 'utils.rb:193'
    frame #0: 0x00007fff7279f882 libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff72860425 libsystem_pthread.dylib`_pthread_cond_wait + 698
    frame #2: 0x00000001070714b3 libruby.2.5.dylib`gvl_acquire_common + 179
    frame #3: 0x000000010706a482 libruby.2.5.dylib`rb_thread_schedule_limits + 386
    frame #4: 0x000000010706b3a2 libruby.2.5.dylib`rb_threadptr_execute_interrupts + 1474
    frame #5: 0x000000010709c7b9 libruby.2.5.dylib`vm_exec_core + 15817
    frame #6: 0x00000001070ae0a8 libruby.2.5.dylib`vm_exec + 184
    frame #7: 0x00000001070acb56 libruby.2.5.dylib`vm_invoke_proc + 374
    frame #8: 0x00000001070bb384 libruby.2.5.dylib`vm_call0_body + 1236
    frame #9: 0x00000001070a6145 libruby.2.5.dylib`rb_funcallv + 245
    frame #10: 0x0000000107a5b562 init.bundle`rr::TryCatch::doCall(code=140299574741160) at trycatch.cc:85:12
    frame #11: 0x0000000106f45bff libruby.2.5.dylib`rb_protect + 335
    frame #12: 0x0000000107a5b4a6 init.bundle`rr::TryCatch::setupAndCall(state=0x0000700003c937dc, code=140299574741160) at trycatch.cc:79:20
    frame #13: 0x0000000107a5b394 init.bundle`rr::TryCatch::doTryCatch(argc=0, argv=0x00007f9a503604a8, self=&lt;unavailable&gt;) at trycatch.cc:69:20
    frame #14: 0x00000001070b39cc libruby.2.5.dylib`vm_call_cfunc + 284
    frame #15: 0x000000010709af09 libruby.2.5.dylib`vm_exec_core + 9497
    frame #16: 0x00000001070ae0a8 libruby.2.5.dylib`vm_exec + 184
    frame #17: 0x00000001070acb56 libruby.2.5.dylib`vm_invoke_proc + 374
    frame #18: 0x00000001070bb384 libruby.2.5.dylib`vm_call0_body + 1236
    frame #19: 0x00000001070a6145 libruby.2.5.dylib`rb_funcallv + 245
    frame #20: 0x0000000106f45bff libruby.2.5.dylib`rb_protect + 335
    frame #21: 0x0000000107a53c07 init.bundle`rr::Handles::HandleScope(int, unsigned long*, unsigned long) [inlined] rr::Handles::SetupAndCall(state=0x0000700003c941fc, code=140299574741440) at handles.cc:27:10
    frame #22: 0x0000000107a53bef init.bundle`rr::Handles::HandleScope(argc=&lt;unavailable&gt;, argv=0x00007f9a503603c0, self=&lt;unavailable&gt;) at handles.cc:18
    frame #23: 0x00000001070b39cc libruby.2.5.dylib`vm_call_cfunc + 284
    frame #24: 0x000000010709af09 libruby.2.5.dylib`vm_exec_core + 9497
    frame #25: 0x00000001070ae0a8 libruby.2.5.dylib`vm_exec + 184
    frame #26: 0x00000001070acb56 libruby.2.5.dylib`vm_invoke_proc + 374
    frame #27: 0x00000001070bb384 libruby.2.5.dylib`vm_call0_body + 1236
    frame #28: 0x00000001070a6145 libruby.2.5.dylib`rb_funcallv + 245
    frame #29: 0x0000000106f45bff libruby.2.5.dylib`rb_protect + 335
    frame #30: 0x0000000107a54989 init.bundle`rr::Locker::doLock(int, unsigned long*, unsigned long) [inlined] rr::Locker::setupLockAndCall(state=0x0000700003c94c0c, code=140299574741520) at locker.cc:48:13
    frame #31: 0x0000000107a5496f init.bundle`rr::Locker::doLock(argc=&lt;unavailable&gt;, argv=0x00007f9a50360388, self=&lt;unavailable&gt;) at locker.cc:39
    frame #32: 0x00000001070b39cc libruby.2.5.dylib`vm_call_cfunc + 284
    ...
</code></pre><figcaption>thread #41 'utils.rb:193'</figcaption></figure><p></p><p><strong><em>thread #67, name = 'SamplerThread'</em></strong><br>This thread is started along with the v8::Isolate. Its primary job is to <em><a href="https://chromium.googlesource.com/external/v8/+/master/src/sampler.h">periodically sample the state of the VM and optionally, (if used for profiling) the program counter and stack pointer for, the thread that created it.</a></em></p><figure class="kg-card kg-code-card"><pre><code class="language-bash">thread #67, name = 'SamplerThread'
    frame #0: 0x00007fff7279ce36 libsystem_kernel.dylib`semaphore_wait_trap + 10
    frame #1: 0x0000000107c9f053 libv8.dylib`v8::internal::MacOSSemaphore::Wait() + 17
    frame #2: 0x0000000107be2be0 libv8.dylib`v8::internal::RuntimeProfiler::WaitForSomeIsolateToEnterJS() + 70
    frame #3: 0x0000000107c9f1c0 libv8.dylib`v8::internal::SamplerThread::Run() + 34
    frame #4: 0x0000000107c9eb1f libv8.dylib`v8::internal::ThreadEntry(void*) + 60
    ...</code></pre><figcaption>thread #67 'SamplerThread'</figcaption></figure><p>We have removed all threads except  <strong><em>thread #6</em></strong> and <strong><em>thread #41 </em></strong>from our list of suspects. It is time for us to look at both of them together. </p><p><strong><em>thread #6</em></strong>,<strong><em> </em></strong>a user-land Ruby thread is holding the GVL and is trying to lock the v8::Isolate through the ffi given by therubyracer. </p><p><strong><em>thread #41</em></strong><em>,</em><strong><em> </em></strong>a native thread is holding the v8::Isolate lock and is trying to acquire GVL. </p><p><strong><em>In short, we have a deadlock. </em></strong></p><h2 id="conclusion">Conclusion</h2><p>Once I identified the cause of this deadlock, which is therubyracer gem being not thread safe, it was time to look for its usage within our application. I found that we were using <a href="https://github.com/cowboyd/handlebars.rb">Handlebars.rb gem</a> to render customizable templates, and Handlebars had therubyracer as one of it dependencies.</p><p>Solutions were either to add a global mutex which would allow only one thread to enter Handlebar's context or to move away from HandleBars to something like <a href="https://github.com/Shopify/liquid">Liquid templating by Shopify</a>. In the end decided to move to Liquid.</p><p></p><p><strong><em>References</em></strong></p><ul><li><a href="https://v8docs.nodesource.com/">V8 Docs by nodesource.com</a> </li><li><a href="https://github.com/rubyjs/therubyracer">The Ruby Racer gem source code</a></li><li><a href="https://lldb.llvm.org/use/tutorial.html">lldb tutorial and documentation by llvm.org</a></li><li><a href="https://stackoverflow.com/questions/15596083/what-is-the-correct-way-to-use-v8locker-and-why-must-i-use-it">Correct way to use a v8::Isolate, StackOverflow</a></li></ul><p><em><strong>Suggested Reading</strong></em></p><ul><li><a href="https://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil"><em>Nobody understands the GIL</em> blog series</a> by <a href="https://twitter.com/jstorimer">Jesse Storimer</a></li><li><a href="https://www.mikeperham.com/2016/08/05/debugging-stuck-ruby-processes/"><em>Debugging a stuck process</em></a> by <a href="https://github.com/mperham">Mike Perham</a></li></ul><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Understanding Ruby Refinements by implementing hash#with_indifferent_access]]></title><description><![CDATA[<p></p><p>As Rails developers, most of us must have come across this handy method, <strong>Hash<em>#with_indifferent_access</em></strong>, another instance of "rails-magic" that lets us access values from a ruby hash using either strings or symbols.</p><pre><code class="language-ruby">require 'active_support/core_ext/hash'

:0&gt; 🚘 = {
:1*  make: 'emoji',
:1*  model: 'Red-car'
:1&</code></pre>]]></description><link>https://midhunkrishna.in/ruby-refinement/</link><guid isPermaLink="false">5f54f44d0379ed43f3a78c83</guid><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Sun, 04 Oct 2020 12:59:51 GMT</pubDate><content:encoded><![CDATA[<p></p><p>As Rails developers, most of us must have come across this handy method, <strong>Hash<em>#with_indifferent_access</em></strong>, another instance of "rails-magic" that lets us access values from a ruby hash using either strings or symbols.</p><pre><code class="language-ruby">require 'active_support/core_ext/hash'

:0&gt; 🚘 = {
:1*  make: 'emoji',
:1*  model: 'Red-car'
:1&gt; }.with_indifferent_access
=&gt; {"make"=&gt;"emoji", "model"=&gt;"red-car"}

:0&gt; puts 🚘[:make]
=&gt; "emoji"
:0&gt; puts 🚘["make"]
=&gt; "emoji"</code></pre><p>In this post, I will be discussing three different ways to implement this functionality and compare and contrast each of these techniques. </p><h2 id="patching-the-core-hash-class-monkey-patch">Patching the core Hash class / Monkey Patch</h2><p>The most straightforward approach of the three is implementing this functionality by patching the core Hash class. </p><pre><code class="language-ruby">class Hash 
  def [](key)
    dig(key.to_s) || dig(key.to_sym)
  end

  def []=(key, value)
    dig(key.to_sym) ? store(key.to_sym, value) : store(key.to_s, value)
  end
end</code></pre><p>In the above code snippet, we are opening and re-implementing a core class. A side effect of this approach is, from that point when this class is loaded, all instances of Hash implements this new behavior and thereby violates the <a href="https://thoughtbot.com/blog/back-to-basics-solid#openclosed-principle">Open/Closed Principle</a> (OCP).</p><p>A technique to extend the behavior of Hash without violating OCP is by using inheritance. This is also how Rails provides indifferent access. </p><h3 id="the-rails-way">The Rails Way</h3><p>If we open Rails console and check the class name of the object returned by calling <strong><em>#with_indifferent_access</em></strong>, we see that, it is no longer Hash, but it is <strong><em>ActiveSupport::HashWithIndifferentAccess.</em></strong></p><pre><code class="language-ruby">[1] pry(main)&gt; {}.class.name
=&gt; "Hash"
[2] pry(main)&gt; {}.with_indifferent_access.class.name
=&gt; "ActiveSupport::HashWithIndifferentAccess"</code></pre><p>If we dig up the <a href="https://github.com/rails/rails/blob/b2eb1d1c55a59fee1e6c4cba7030d8ceb524267c/activesupport/lib/active_support/hash_with_indifferent_access.rb">source code we can see that, <strong><em>HashWithIndifferentAccess</em></strong></a><strong><em> </em></strong>inherits from Hash. </p><pre><code class="language-ruby">module ActiveSupport
  class HashWithIndifferentAccess &lt; Hash
    def initialize
      # ...
    end
    
    def [](key)
      dig(key.to_s) || dig(key.to_sym)
    end

    def []=(key, value)
      dig(key.to_sym) ? store(key.to_sym, value) : store(key.to_s, value)
    end

    # NOTE:
    # The actual HashWithIndifferentAccess implementation 
    # does a lot more than re-implement #[] and #[]=
  end
end

class Hash
  def with_indifferent_access
    HashWithIndifferentAccess.new(self)
  end
end</code></pre><p>This technique doesn’t change the implementation of any of the interfaces of the core class, but has a major downside, which is one needs to install and use <a href="https://github.com/rails/rails/tree/master/activesupport">ActiveSupport gem</a>. </p><p>While working on a gem, I thought it would be a bit too much to include ActiveSupport as a dependency just for the ability to access a hash value with either a string or a symbol and that is when I came across Ruby Refinements. </p><h3 id="let-s-refine-hash-">Let's Refine Hash!</h3><p>Ruby Refinements, as the name suggests allow us to modify the functionality of a class with very minimal impact. In fact, refinements were introduced to minimize the impact of monkey-patching core classes. </p><pre><code>module DifferentlyAccessibleHash
  refine Hash do
    def [](key)
      dig(key.to_s) || dig(key.to_sym)
    end

    def []=(key, value)
      dig(key.to_sym) ? store(key.to_sym, value) : store(key.to_s, value)
    end
  end
end</code></pre><p>Take a note of the <strong><em>Module#refine</em></strong><em><strong> </strong></em>keyword in line#2. Adapting <a href="https://docs.ruby-lang.org/en/2.4.0/syntax/refinements_rdoc.html#label-Refinements">Ruby documentation</a> for our example above, we have the following. </p><ul><li><strong>Module<em>#refine </em></strong>keyword is used to refine an existing class Hash. </li><li><strong>Module</strong><em><strong>#refine </strong></em>creates an anonymous module and this anonymous module can be <strong><em>"activated" </em></strong>by employing the <strong><em>using </em></strong>keyword. </li></ul><p>This is a bit confusing, correct? <strong><em> </em></strong>Let's try to explain this with a code snippet. </p><pre><code class="language-ruby"># differently_accessible_hash.rb

module DifferentlyAccessibleHash
  refine Hash do
    def [](key)
      dig(key.to_s) || dig(key.to_sym)
    end

    def []=(key, value)
      dig(key.to_sym) ? store(key.to_sym, value) : store(key.to_s, value)
    end
  end
end

# car.rb

require './differently_accessible_hash'

class EmojiCar

  using DifferentlyAccessibleHash
  
  def initialize
    @specs = { 
     make: 'emoji',
     model: 'Red-car'
    }
  end
  
  def make
    @specs[:make]   # access make via symbol
  end
  
  def model
    @specs['model'] # access model via string 
  end
end
</code></pre><p>Even though <strong>Module<em>#refine </em></strong>creates an anonymous module with our new functionality against Hash, this module is not activated until the usage of <em><strong>using </strong></em>keyword. </p><p>Another advantage of the <strong><em>using</em></strong> keyword is that, it is lexically scoped. From the documentation.</p><!--kg-card-begin: markdown--><blockquote>
<ul>
<li>You may activate refinements at top-level, and inside classes and modules.</li>
<li>You may not activate refinements in method scope.</li>
<li>Refinements are activated until the end of the current class or module definition, or until the end of the current file if used at the top-level.</li>
<li>Refinements are only active within a scope after the call to using. Any code before the using statement will not have the refinement activated</li>
</ul>
</blockquote>
<!--kg-card-end: markdown--><p>In our example code, since we have <em><strong>"activated" </strong></em>DifferentlyAccessibleHash in the class level, any Hash objects can be accessed with either string or symbol within that class. </p><h2 id="additional-reading">Additional Reading</h2><p><a href="https://medium.com/rubycademy/refine-and-using-methods-in-ruby-part-i-2aef6d7a4325"><strong>Refine and Using Methods in Ruby</strong> by Mehdi Farsi</a><br><a href="https://avdi.codes/so-whats-the-deal-with-ruby-refinements-anyway/"><strong>So what’s the deal with Ruby refinements, anyway?</strong> by Avdi Grimm</a></p>]]></content:encoded></item><item><title><![CDATA[An Introduction to Ruby Modules]]></title><description><![CDATA[<p></p><h2 id="a-not-so-gentle-introduction">A not so gentle Introduction</h2><p>Modules are some of the most exciting concepts in Ruby, but it is also a feature that is not really understood by its users. For someone who is just starting out with the language and even to seasoned programmers, Ruby Modules can be confusing, especially</p>]]></description><link>https://midhunkrishna.in/an-introduction-to-ruby-modules/</link><guid isPermaLink="false">5f5e2fcc0379ed43f3a78ebb</guid><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Sun, 13 Sep 2020 14:42:58 GMT</pubDate><content:encoded><![CDATA[<p></p><h2 id="a-not-so-gentle-introduction">A not so gentle Introduction</h2><p>Modules are some of the most exciting concepts in Ruby, but it is also a feature that is not really understood by its users. For someone who is just starting out with the language and even to seasoned programmers, Ruby Modules can be confusing, especially when used in conjunction with classes.</p><!--kg-card-begin: markdown--><p>Before we start on this post, let me give you a 10,000ft over-view of how this post is structured. The post takes you through</p>
<ul>
<li>Different ways of using modules</li>
<li>Anonymous Modules and a Rails use case</li>
<li>In closing, a brief history of module system</li>
</ul>
<!--kg-card-end: markdown--><h2 id="how-can-i-use-modules">How can I use modules?</h2><h3 id="enhancing-the-behavior-of-an-instance-">Enhancing the behavior of an instance.</h3><p>A good way to enhance the capabilities of an instance is to 'mix-in' a module into its class.</p><pre><code class="language-ruby">module Saveable
  def save
  end
end

class XMLDocument
  include Saveable
end

:0&gt; xml_document = XMLDocument.new
:0&gt; xml_document.respond_to? :save
=&gt; true
</code></pre><p>Here, when <strong><em>Saveable</em></strong> module is included, the behavior of the original XMLDocument changes. It can be saved to the disk now.</p><p>Another way to look at this is, now instance-methods of XMLDocument can access #save method of <strong><em>Saveable </em></strong>module, which opens up additional possibilities like overriding the default behavior.</p><pre><code class="language-ruby">class XMLDocument
  include Saveable
  
  def save
    puts @data.inspect
    super
  end
end   </code></pre><p>But why <strong><em>super</em></strong> ? To understand that, let's look at what super is.  </p><p>By definition,</p><blockquote>super: Calls the current method in a superclass</blockquote><p>When we included Saveable into XMLDocument, Saveable became a <code>super</code> from which behavior is inherited. This becomes even more evident when we inspect the ancestors of XMLDocument.</p><pre><code class="language-ruby">:0&gt; XMLDocument.ancestors
=&gt; [XMLDocument, Saveable, Object, Kernel, BasicObject]
</code></pre><p>We can see that sum-total of XMLDocument is the final inheritance or rather a mixin from itself as well as from a bunch of other classes and modules.</p><p>There are few other ways to share code between classes like Multiple Inheritance and <a href="https://en.wikipedia.org/wiki/Trait_(computer_programming)">Traits</a>. Ruby doesn't support Multiple Inheritance.</p><p>Quoting Matz,</p><blockquote>Single inheritance is good because the whole class inheritance structure forms a single tree with a single root, named Object, and that is very easy to understand. In languages with multiple inheritance, the classes form a network, which is harder to understand.</blockquote><p>reference: <a href="https://web.archive.org/web/20191025214218/https://www.artima.com/intv/tuesday.html">https://web.archive.org/web/20191025214218/https://www.artima.com/intv/tuesday.html</a></p><p>Now that we have a clear idea of what <strong><em>include</em></strong> is, how to use it, and why is it designed that way, let's move on to the next way to use modules.</p><h3 id="enhancing-the-behavior-of-a-class">Enhancing the behavior of a Class</h3><p>The way we can enhance the behavior of a Class is through the use of <code>extend</code> keyword.</p><pre><code class="language-ruby">module FileReadable
  def read(file_path)
    # reads the file at file_path
  end
end

class XMLDocument
  extend FileReadable
end

:0&gt; xml_document = XMLDocument.read('/path/to/file.xml')
</code></pre><p>When we extended XMLDocument with FileReadable, functions on FileReadable became class methods of XMLDocument.</p><p>Even though <strong><em>extend</em></strong> lends a module's behavior to a class, ( as opposed to include which lends the behavior to an instance) the way <strong><em>extend</em></strong> works internally is very similar to include keyword.</p><p>But, let's digress to explore the subject of class or static methods in Ruby.</p><pre><code class="language-ruby">class XMLDocument
  def self.parse(raw_data)
  end
end

:0&gt; XMLDocument.singleton_class.instance_methods.grep /parse/
=&gt; [:parse]
</code></pre><p>In essence, every class method of XMLDocument is in reality, instance methods of XMLDocument's singleton or eigen or metaclass.</p><p>From Wikipedia,</p><blockquote>A metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances.</blockquote><p>So far, we know the following:</p><ul><li>An eigen class defines the behavior of a class</li><li>Class methods are instance methods on the eigen-class of a class</li><li>Include keyword added instance methods by pushing Saveable module up the ancestor chain or XMLDocument</li></ul><pre><code class="language-ruby">:0&gt; XMLDocument.singleton_class.ancestors
=&gt; [#&lt;Class:XMLDocument&gt;, FileReadable, #&lt;Class:Object&gt;, #&lt;Class:BasicObject&gt;, Class, Module, Object, Kernel, BasicObject]

</code></pre><p>In conclusion, <strong><em>extend</em></strong> keywork added instance methods to the metaclass of XMLDocument by pushing FileReadable module into its ancestor chain.</p><h3 id="decorating-the-existing-behavior-of-an-instance-">Decorating the existing behavior of an instance.</h3><p>As its name suggests, <strong><em>prepend</em></strong> keyword prepends the behavior of a module before the instance's.</p><p>In one of our previous examples I have an XMLDocument with save capabilities, if we, for example, want to measure how many seconds it would take for save operation to complete.</p><pre><code class="language-ruby">module Saveable
  def save
  end
end

class XMLDocument
  include Saveable
end

module Timer
  def save
    t1 = Time.now
    super
    puts "Time taken to save: #{Time.now - t1}s"
  end
end

XMLDocument.prepend(Timer)

:0&gt; xml_document = XMLDocument.new
:0&gt; xml_document.save
Time taken to save: 0.084587s
=&gt; nil
</code></pre><p>By just looking at the code, you my esteemed reader, might have guessed exactly what is going on under the hood. Let's inspect the ancestors chain again.</p><pre><code>:0&gt; XMLDocument.ancestors
=&gt; [Timer, XMLDocument, Saveable, Object, Kernel, BasicObject]
</code></pre><h3 id="classes-with-just-class-methods">Classes with just class methods</h3><p>In our careers, we might have come across a fully functional class that has just class methods. A prime example is the quintessential kitchen-sink, the Util class. </p><pre><code class="language-ruby">class Util
  def self.do_something
  end
  
  def self.do_something_entirely_different
  end
end</code></pre><p>This is an anti-pattern and is declining rapidly, thanks to RuboCop. This can be readily replaced by.</p><pre><code class="language-ruby">module Util
  module_function
  
  def do_something
  end
  
  def do_something_entirely_different
  end
end</code></pre><p>Now that we know the many different direct use cases of modules, let us look at namespacing.</p><h3 id="a-way-to-logically-bundle-things-">A way to logically bundle things. </h3><p>Any programmer knows that "Fruits::Apple" must be something completely different from "CellPhone::Apple", we also know that "CellPhone::Apple" might be similar to "CellPhone::Nokia", hence we conclude with little-evidence that Namespacing has nothing to do with names and much more to do with similarity. </p><!--kg-card-begin: markdown--><p>I won't be going much into namespaces and constant resolution, due to the simple fact that, the topic in itself is vast and can't beat these follwoing writeups as these posts discusses namespaces and constant resolution in great depth.</p>
<ul>
<li>This <a href="https://web.archive.org/web/20200413115214/https://cirw.in/blog/constant-lookup.html">excellent writeup by Conrad Irvin</a> about Constant Resolution is a must read for every Ruby practitioner</li>
<li>This <a href="https://web.archive.org/web/20200221053802/https://rubymonk.com/learning/books/1-ruby-primer/chapters/35-modules/lessons/80-modules-as-namespaces">primer on namespaces written by Sidu Ponnappa and Jasim A Basheer</a> for RubyMonk</li>
</ul>
<!--kg-card-end: markdown--><h3 id="as-a-transitive-container-to-hold-code">As a transitive container to hold code </h3><p>To understand this a bit more, let us look into the ways in which a module can be defined in Ruby code. </p><pre><code class="language-ruby">module Sidekiq
end</code></pre><p>and the above form is very much equivalent to the following code.</p><pre><code class="language-ruby">Sidekiq = Module.new do
end
</code></pre><p>Even though these are two forms are same for all intents and purposes, there is a subtle difference. The second form, takes an <strong><em>anonymous </em></strong>module and assigns it to a constant, while in first form there is no anonymous module involved due to the implicit assignment of the module code to the constant. </p><p>An example of anonymous module in action is <strong><em>class_methods</em></strong> from <strong><em>ActiveSupport::Concern. </em></strong>I am sure you, my reader, is extremely inquisitive and would love to find out how that works. </p><!--kg-card-begin: markdown--><p>the tl;dr version.</p>
<ul>
<li>The block of code passed to <em><strong>classmethods</strong></em> is assigned to an anonymous module</li>
<li>This anonymous module is then used to append class methods to the including class using <em><strong>extend</strong></em></li>
</ul>
<!--kg-card-end: markdown--><p>I have an explanation of <a href="https://midhunkrishna.in/private_class_methods-similar-to-activesupport-concern-class_methods/#how-far-can-we-go-with-this">how it works in one of my previous blogs</a>, ( and the link points to <em>just that</em> section ).</p><p>We have exhausted all the possible ways we can use modules in Ruby. Let us learn a bit more, and read the fantastic history of modules. </p><h2 id="a-brief-history-of-module-system">A Brief history of module system</h2><p>When Matz designed Ruby, he was heavily inspired by SmallTalk which is often considered as the perfect Object Oriented language. Ruby inherited a lot of features from SmallTalk, <a href="https://en.wikipedia.org/wiki/Smalltalk#:~:text=Smalltalk%2D80%20added%20metaclasses%2C%20to,different%20ways%20to%20create%20instances).">including MetaClass ( references in above section, Enhancing the behavior of a Class), to help maintain the "everything is an object" paradigm</a>.</p><p>Even though SmallTalk is an Object Oriented language, from the perspective of its original designers, Alan Kay, Dan Ingalls, Adele Goldberg, and others at Xerox PARC, SmallTalk was designed as a functional language based on Lisp and Simula of which Simula supported features like Objects and Classes. One can argue that, while Lisp gave functional programming capabilities to SmallTalk, Simula gave it the "object-orientedness", like Classes and Objects.</p><p>But where does the module system come from? To answer this question, we need to go further back another generation. The immediate generation of <a href="https://web.archive.org/web/20200215003716/http://linuxfinances.info/info/pascal.html">The PASCAL Family</a> of Programming Languages.  This family contains heavyweights like Ada, Simula, Eiffel and a lesser known Modula. It is Modula that brought forth modularization, the idea that "lets one define a public interface to hide the private implementation details".</p>]]></content:encoded></item><item><title><![CDATA[Understanding binding.pry]]></title><description><![CDATA[<p>I have been using <a href="https://github.com/pry/pry">Pry as a repl and as a debugging tool for Ruby</a> for as long as I can remember. I am a proficient user of the tool, but so far, I haven't put any effort to understand <strong>how</strong> Pry debugger works. </p><p>Together, let's learn how Pry debugger</p>]]></description><link>https://midhunkrishna.in/understanding-binding-pry/</link><guid isPermaLink="false">5f3ce3c70379ed43f3a78ac9</guid><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Thu, 20 Aug 2020 17:32:43 GMT</pubDate><content:encoded><![CDATA[<p>I have been using <a href="https://github.com/pry/pry">Pry as a repl and as a debugging tool for Ruby</a> for as long as I can remember. I am a proficient user of the tool, but so far, I haven't put any effort to understand <strong>how</strong> Pry debugger works. </p><p>Together, let's learn how Pry debugger works, but before we dive into that, we need to do some ground work and learn what <em><strong>binding</strong></em> is.</p><p>From Ruby documentation, </p><blockquote>Objects of class <strong>Binding</strong> encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of <strong>self</strong> , and possibly an iterator block that can be accessed in this context are all retained. </blockquote><p>Let us use (a modified version) the sample code given in the documentation to understand this concept a bit more. </p><pre><code class="language-ruby">class Demo
  def initialize(message)
    @message = message
  end
  
  def get_binding
    binding
  end
end

irb:xx&gt; demo_binding = Demo.new('fantastic').get_binding
irb:xx&gt; puts demo_binding.eval("It has been a #{@message} demo")
It has been a fantastic demo
nil
irb:xx&gt;</code></pre><p>In essence, <strong><em>binding.eval</em></strong> executes any 'code-string' in the context of the object at the point at which the binding was captured. </p><h3 id="what-is-binding-pry">What is <em>binding.pry?</em></h3><p>Pry debugger extends Ruby's Binding class to start a REPL whenever <strong><em>#pry</em></strong> is called on a binding. The REPL is started in such a way that the REPL's context is the binding itself. </p><p>Let's try to mimic this, with a barebones implementation.</p><pre><code class="language-ruby">class Binding
  # We are opening and patching Ruby's in-built Binding class
  # and adding a new method: #pry
  
  def pry
    # Our humble read-eval-print-loop
    loop do
      puts self.eval(gets)
    end
  end
end

class Demo
  def initialize(message)
    @message = message
  end

  def get_binding
    binding
  end
  
  def start_pry
    binding.pry
  end
end

irb:xx&gt; demo = Demo.new("simple repl")
=&gt; #&lt;Demo:0x00007fa8d61677a0 @message="simple repl"&gt;

irb:xx&gt; demo.start_pry
puts "This is a #{@message}"
This is a simple repl
</code></pre><p>At its core, Pry  is as simple as this, but in its entirety, Pry is much more. Our barebones implementation lacks a prompt and bombs when we try to evaluate multi-line code. Pry uses <a href="https://ruby-doc.org/stdlib-2.5.1/libdoc/readline/rdoc/Readline.html">Ruby Readline</a> to handle all these cases and as a cherry on top, uses <a href="https://github.com/rubychan/coderay">coderay</a> to highlight the code. </p>]]></content:encoded></item><item><title><![CDATA[Rails 6 adds guard against DNS Rebinding attacks]]></title><description><![CDATA[<p>In a DNS Rebinding attack, a malicious webpage runs client-side script when it is loaded, to attack endpoints within a given network.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2019/11/05/rails-6-adds-guard-against-dns-rebinding-attacks.html">Rails 6 adds guard against DNS Rebinding attacks</a></p>]]></description><link>https://midhunkrishna.in/rails-6-adds-guard-against-dns-rebinding-attacks/</link><guid isPermaLink="false">5f3a829b0379ed43f3a78a26</guid><category><![CDATA[ruby]]></category><category><![CDATA[rails]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Tue, 05 Nov 2019 06:40:00 GMT</pubDate><content:encoded><![CDATA[<p>In a DNS Rebinding attack, a malicious webpage runs client-side script when it is loaded, to attack endpoints within a given network.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2019/11/05/rails-6-adds-guard-against-dns-rebinding-attacks.html">Rails 6 adds guard against DNS Rebinding attacks</a></p>]]></content:encoded></item><item><title><![CDATA[Rails 6 introduces new code loader: Zeitwerk]]></title><description><![CDATA[<p><a href="https://github.com/fxn/zeitwerk">Zeitwerk</a> is the new code loader that <a href="https://weblog.rubyonrails.org/2019/2/22/zeitwerk-integration-in-rails-6-beta-2#autoloading-modes">comes with Rails 6 by default</a>. In addition to providing <a href="https://guides.rubyonrails.org/autoloading_and_reloading_constants.html">autoloading, eager loading, and reloading capabilities</a>, it also improves the classical code loader by being efficient and thread safe. According to the author of Zeitwerk, <a href="https://twitter.com/fxn">Xavier Noria</a>, one of the main motivations for</p>]]></description><link>https://midhunkrishna.in/rails-6-introduces-new-code-loader-called-zeitwerk/</link><guid isPermaLink="false">5f3a83030379ed43f3a78a38</guid><category><![CDATA[rails]]></category><category><![CDATA[ruby]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Tue, 08 Oct 2019 13:16:00 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://github.com/fxn/zeitwerk">Zeitwerk</a> is the new code loader that <a href="https://weblog.rubyonrails.org/2019/2/22/zeitwerk-integration-in-rails-6-beta-2#autoloading-modes">comes with Rails 6 by default</a>. In addition to providing <a href="https://guides.rubyonrails.org/autoloading_and_reloading_constants.html">autoloading, eager loading, and reloading capabilities</a>, it also improves the classical code loader by being efficient and thread safe. According to the author of Zeitwerk, <a href="https://twitter.com/fxn">Xavier Noria</a>, one of the main motivations for writing Zeitwerk was to keep code DRY and to remove the brittle <code>require</code> calls.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2019/10/08/rails-6-introduces-new-code-loader-called-zeitwerk.html">Rails 6 introduces new code loader called Zeitwerk</a></p>]]></content:encoded></item><item><title><![CDATA[private_class_methods similar to ActiveSupport::Concern class_methods]]></title><description><![CDATA[<p>A while back, the CTO of my client company assigned me a ticket, which was to fix a bug that has been plaguing their systems for a while. It turned out to be a bug in the custom serializer they had, which would serialize and deserialize data sent between their</p>]]></description><link>https://midhunkrishna.in/private_class_methods-similar-to-activesupport-concern-class_methods/</link><guid isPermaLink="false">5f3a7b710379ed43f3a78a0e</guid><category><![CDATA[ruby]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Wed, 20 Feb 2019 04:40:00 GMT</pubDate><content:encoded><![CDATA[<p>A while back, the CTO of my client company assigned me a ticket, which was to fix a bug that has been plaguing their systems for a while. It turned out to be a bug in the custom serializer they had, which would serialize and deserialize data sent between their micro-services.</p><p>This serializer was small enough to be written in a single class and had two or three methods which did all the heavy lifting and obviously were fat. After combing through the implementation for a while and testing it with data, I finally figured out the bug it carried and fixed it, but the fat methods were an eyesore, and like a good boy scout, I decided to refactor it.</p><p>The serializer dealt with no state at all which meant that the methods were all class methods, and splitting up class methods are always a pain.</p><pre><code class="language-ruby">class CustomSerializer
  def self.serialize(objects, options={})
    list = associated_records(objects, options)
    unwanted_associations = blacklisted_associations(options)
    unwanted_attributes = blacklisted_attributes(options)

    list.each do | object, associations |
      remove_blacklisted_associations(associations, unwanted_associations)
      # you get the idea
    end
  end

  def self.deserialize(json, options={})
  end

  def self.blacklisted_associations(options)
  end

  def self.blacklisted_attributes(options)
  end

  def self.associated_records(options)
  end
end</code></pre><p></p><p>These methods, are only usable within the context of the class, and usually, we hide them using access modifiers, but how does one hide a class method?</p><h2 id="private-class-methods-to-the-rescue-"><strong>Private Class Methods To The Rescue.</strong></h2><p>As discussed in <a href="http://ruby-doc.org/core-2.0.0/Module.html#method-i-private_class_method">ruby docs </a>, <code>private_class_methods</code> are used to make existing class methods hidden.</p><pre><code class="language-ruby">class SimpleSingleton  # Not thread safe
  private_class_method :new
  def SimpleSingleton.create(*args, &amp;block)
    @me = new(*args, &amp;block) if ! @me
    @me
  end
end</code></pre><p></p><p>In the above example, taken from the docs, it hides the constructor :new. But what happens when you have one too many class methods you need to hide?.</p><p>Incorporating private_class_method into our earlier class, it becomes,</p><pre><code class="language-ruby">class CustomSerializer
  def self.serialize(objects, options={})
    # code
  end

  def self.deserialize(json, options={})
    # code
  end

  def self.blacklisted_associations(options)
  end

  def self.blacklisted_attributes(options)
  end

  def self.associated_records(options)
  end

  private_class_method :blacklisted_associations, :blacklisted_attributes, :associated_records
end</code></pre><p></p><p>This works!, but what if the class is very large that I need to scroll all the way down to see which ones are private class methods? If only I had something similar to <a href="http://api.rubyonrails.org/classes/ActiveSupport/Concern.html#method-i-class_methods">class_methods from ActiveSupport::Concern</a></p><p>Let’s take a quick detour and see what public methods are.</p><h2 id="public-methods-in-ruby"><strong>Public Methods In Ruby</strong></h2><p>Let's take any public method from the above class and look at it a little deeper.</p><pre><code class="language-ruby">class CustomSerializer
  def self.associated_records
  end
end

# :irb &gt; CustomSerializer.public_methods.grep /associated_records/
# =&gt; [:associated_records]

# :irb &gt; CustomSerializer.singleton_class.instance_methods.grep /associated_records/
# =&gt; [:associated_records]</code></pre><p>Basically, class methods are instance methods of any class’s singleton_class or <a href="https://github.com/ruby/ruby/blob/v2_5_0/class.c#L15-L22">eigenclass. </a>This basically means that we can do something like:</p><pre><code class="language-ruby">class CustomSerializer
  class &lt;&lt; self
    private

    def associated_records
    end
  end
end

# :irb &gt; CustomSerializer.public_methods.grep /associated_records/
# =&gt; []

# :irb &gt; CustomSerializer.associated_records
# NoMethodError: private method `associated_records' called for CustomSerializer:Class
#   from (irb):xx

# :irb &gt; CustomSerializer.singleton_class.private_instance_methods.grep /associated_records/
# =&gt; [:associated_records]</code></pre><p></p><p>We now have a way to avoid the repetition and to improve the readability of the code. Only problem is, do all of us understand what is going on here? Ruby as a language gives us immense meta-programming flexibility and I decided to take this even further.</p><h2 id="how-far-can-we-go-with-this"><strong>How Far Can We Go With This?</strong></h2><p>Remember the <code>class_methods</code> method defined on module from ActiveSupport::Concern? Will ruby allow us to do something like that?. Lets take a look at the source code for <code>class_methods</code> from ActiveSupport::Concern.</p><pre><code class="language-ruby"># File activesupport/lib/active_support/concern.rb, line 134
def class_methods(&amp;class_methods_module_definition)
  mod = const_defined?(:ClassMethods, false) ?
    const_get(:ClassMethods) :
    const_set(:ClassMethods, Module.new)

  mod.module_eval(&amp;class_methods_module_definition)
end</code></pre><p></p><p>The following is what happens when that method is executed:</p><ul><li>The method <code>class_methods</code> checks whether there is an already existing constant, <code>:ClassMethods</code></li><li>If it is not present, instantiate an anonymous module and set it to local variable <code>mod</code></li><li>Runs <code>module_eval on mod</code> with the given block.</li></ul><p>Let’s decipher what ActiveSupport does here by trying this out on the console and filling the blanks whenever necessary.</p><pre><code class="language-ruby">module Holder
  mod = const_set :ClassMethods, Module.new
  mod.module_eval do
    def associated_records
    end
  end
end

# :irb &gt; Holder::ClassMethods.class
# =&gt; Module

class CustomSerializer
  extend Holder::ClassMethod
end

# :irb &gt; CustomSerializer.singleton_class.instance_methods.grep /associated_records/
# =&gt; [:associated_records]</code></pre><p></p><p>In short, ActiveSupport::Concern uses an anonymous class as a temporary storage. But can we use this to create a helper of our own? This is what I came up with.</p><pre><code class="language-ruby">class Object
  def private_class_methods &amp;block
    anonymous_module = Module.new(&amp;block)
    anonymous_module.instance_methods.each { |method| anonymous_module.send(:private, method) }
    extend(anonymous_module)
  end
end

class CustomSerializer
  private_class_methods do
    def associated_records
    end
  end
end

# :irb &gt; CustomSerializer.singleton_class.private_instance_methods.grep /associated_records/
# =&gt; [:associated_records]</code></pre><p></p><h2 id="getting-back-to-our-refactor"><strong>Getting Back To Our Refactor</strong></h2><p>In the end, I went with the <code>private_class_methods :method_A, :method_B</code>. Why, one might ask. I went through the code base and checked for usages of private_class_method and for classes that could use this helper. I couldn't find much. I checked for the churn of CustomSerializer class. It was very low, and again, this new method isn't documented anywhere so, another developer will have to grep through the codebase to find its definition.</p><p>In the end cons associated with patching a core class outweighed the pros of having a handy helper.</p><blockquote>Update: <a href="https://ruby-doc.org/core-2.6.3/Module.html#method-i-module_function">For encapsulating stateless code, a module with .module_functions is favored over a class with only class methods in idiomatic ruby.</a></blockquote>]]></content:encoded></item><item><title><![CDATA[Setting up a high performance Geocoder]]></title><description><![CDATA[<p>One of our applications uses geocoding extensively. When we started the project, we included the excellent <a href="https://github.com/alexreisner/geocoder">Geocoder gem</a>, and set <a href="https://developers.google.com/maps/documentation/geocoding/start">Google</a> as the geocoding backend. As the application scaled, its geocoding requirements grew and soon we were looking at geocoding bills worth thousands of dollars.</p><p>Read more about this at:</p>]]></description><link>https://midhunkrishna.in/setting-up-a-high-performance-geocoder/</link><guid isPermaLink="false">5f3a83550379ed43f3a78a47</guid><category><![CDATA[rails]]></category><category><![CDATA[ruby]]></category><category><![CDATA[geocoding]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Tue, 21 Aug 2018 04:30:00 GMT</pubDate><content:encoded><![CDATA[<p>One of our applications uses geocoding extensively. When we started the project, we included the excellent <a href="https://github.com/alexreisner/geocoder">Geocoder gem</a>, and set <a href="https://developers.google.com/maps/documentation/geocoding/start">Google</a> as the geocoding backend. As the application scaled, its geocoding requirements grew and soon we were looking at geocoding bills worth thousands of dollars.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2018/08/21/setting-up-a-high-performance-geocoder.html">Setting up a high performance Geocoder.</a></p>]]></content:encoded></item><item><title><![CDATA[Using Concurrent Ruby in a Ruby on Rails Application]]></title><description><![CDATA[<p><a href="https://github.com/ruby-concurrency/concurrent-ruby">Concurrent Ruby</a> is a concurrency toolkit that builds on a lot of interesting ideas from many functional languages and classic concurrency patterns. When it comes to writing threaded code in Rails applications, look no further since concurrent ruby is <a href="https://github.com/rails/rails/blob/565ce0eaba233fcdd196c11715a8740bd571fd31/activesupport/activesupport.gemspec#L33">already included in Rails</a> via Active Support.</p><p>Read more about this</p>]]></description><link>https://midhunkrishna.in/using-concurrent-ruby-in-a-ruby-on-rails-application/</link><guid isPermaLink="false">5f3a7a2d0379ed43f3a789fc</guid><category><![CDATA[rails]]></category><category><![CDATA[ruby]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Mon, 06 Aug 2018 12:39:00 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://github.com/ruby-concurrency/concurrent-ruby">Concurrent Ruby</a> is a concurrency toolkit that builds on a lot of interesting ideas from many functional languages and classic concurrency patterns. When it comes to writing threaded code in Rails applications, look no further since concurrent ruby is <a href="https://github.com/rails/rails/blob/565ce0eaba233fcdd196c11715a8740bd571fd31/activesupport/activesupport.gemspec#L33">already included in Rails</a> via Active Support.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2018/06/05/using-concurrent-ruby-in-a-ruby-on-rails-application.html">Using concurrent Ruby in a Ruby on Rails Application.</a></p>]]></content:encoded></item><item><title><![CDATA[CTEs And Window Functions]]></title><description><![CDATA[<h3></h3><p>I am a big fan of code readability, but being a fan and expecting the code I write to be readable are two different things. Readable code is easier to understand and much more straightforward to grasp.</p><p>One significant difference I find while comparing readable and unreadable code, apart from</p>]]></description><link>https://midhunkrishna.in/ctes-and-window-functions/</link><guid isPermaLink="false">5f3a66b50379ed43f3a789a8</guid><category><![CDATA[sql]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Tue, 05 Jun 2018 07:00:00 GMT</pubDate><content:encoded><![CDATA[<h3></h3><p>I am a big fan of code readability, but being a fan and expecting the code I write to be readable are two different things. Readable code is easier to understand and much more straightforward to grasp.</p><p>One significant difference I find while comparing readable and unreadable code, apart from the obvious, is how many different variables I have to hold in my head at a time while I try to grapple my head around it. If this task is simple, I believe that this is not because of some random act of brilliance but due to careful code construction.</p><p>CTEs helps achieve this by its ability to separate data into independent logical entities according to the context of the query.</p><figure class="kg-card kg-code-card"><pre><code class="language-sql">WITH popular_posts 
     AS (SELECT id, 
                title, 
                body 
         FROM   posts 
         WHERE  posts.upvote &gt; 5) 
SELECT * 
FROM   popular_posts; </code></pre><figcaption>popular_posts: any post with 6 or more upvotes</figcaption></figure><h3 id="a-random-use-case-">A random use case.   </h3><p>Let's look at a random use case and check how the query performance and readability can be improved. For a particular report in our e-commerce app, we were querying for each item’s latest <strong>n</strong> review-comments, in our case, we can set <strong>n</strong> = 2.</p><p>For the first iteration, we can write a simple join and then filter that in our application language (Ruby, Go, PHP etc.)</p><figure class="kg-card kg-code-card"><pre><code class="language-sql">SELECT items.id             AS item_id, 
       review_comments.id   AS comment_id, 
       review_comments.body AS comment_body
FROM   items 
       LEFT OUTER JOIN review_comments 
                    ON items.id = review_comments.item_id; </code></pre><figcaption>a join table: item and its review comments</figcaption></figure><p></p><p>For an e-commerce system like Amazon, this is not going to scale since the sheer number of items and the associated review comments are guaranteed to bog down the dbms. </p><h3 id="lets-introduce-a-window-function">Lets introduce a Window Function</h3><p>In general, a Window Function, is a mathematical function that is zero valued outside of some interval. In case of SQL engines, they operate on rows that are related to the current row, in our case, this can be the item_id. All rows of the join that has a common item_id acts as a partition over which the window function acts.</p><p>We rewrite our query to do the following:</p><ul><li>Window function should operate on a partition of same item_ids</li><li>Each of these partitions should be ordered by created time stamp of review_comment.</li><li>Select only the top two from each partition</li></ul><figure class="kg-card kg-code-card"><pre><code class="language-sql">SELECT 
  item_id, 
  comment_id, 
  comment_body 
FROM 
  (
    SELECT 
      items.id AS item_id, 
      review_comments.id AS comment_id, 
      review_comments.body AS comment_body, 
      Row_number() OVER(
        partition BY item_id 
        ORDER BY 
          review_comments.created_at DESC
      ) AS comment_row_number, 
    FROM 
      items 
      LEFT OUTER JOIN review_comments ON items.id = review_comments.item_id
  ) AS items_ranked_by_comments 
WHERE 
  comment_row_number &lt; 3;

/* Result:
+----------+------------+--------------------+
|  item_id | comment_id |    comment_body    |
+----------+------------+--------------------+
|      900 |       8789 | This product is..  |
|      900 |      12301 | Fantastic produ..  |
|     1200 |      13466 | Great to see cu..  |
|     1200 |      19023 |                    | 
|       .. |         .. |                ..  |
+----------+------------+--------------------+
*/</code></pre><figcaption>item with at-least two review comments&nbsp;</figcaption></figure><p>The sub-query is resulting in a full join table, but now we have <code>comment_row_number</code> field to let us know that the newest review_comment has a value of 1. All we need to do now is to filter using that column. </p><blockquote>We have used row_number() function from PostgreSQL as the window function here. <a href="https://www.postgresql.org/docs/9.3/static/functions-window.html">According to the docs, </a>any built-in or user-defined aggregate function can be used as a window function.</blockquote><h3 id="putting-it-all-together">Putting It All Together</h3><p>Even though we have our answer, our query has become pretty hard to read. We can get better readability by introducing a <a href="https://www.postgresql.org/docs/9.6/static/queries-with.html">Common Table Expression.</a></p><figure class="kg-card kg-code-card"><pre><code class="language-sql">WITH items_ranked_by_comments AS (
  SELECT 
    items.id AS item_id, 
    review_comments.id AS comment_id, 
    review_comments.body AS comment_body, 
    Row_number() OVER(
      partition BY item_id 
      ORDER BY 
        review_comments.created_at DESC
    ) AS comment_row_number, 
  FROM 
    items 
    LEFT OUTER JOIN review_comments ON items.id = review_comments.item_id
) 
SELECT 
  item_id, 
  comment_id, 
  comment_body 
FROM 
  items_ranked_by_comments 
WHERE 
  comment_row_number &lt; 3;</code></pre><figcaption>CTE implementation of item with at-least 2 review comments.</figcaption></figure><p></p><p>Well, that is it folks. We have put together two concepts, readability and performance to create something which is the best of both worlds.</p>]]></content:encoded></item><item><title><![CDATA[Rails 5 silences assets logs in dev mode by default]]></title><description><![CDATA[<p>As a Rails developer, it was a familiar picture of assets logs flooding the whole terminal in development mode. Fortunately, we could include <code>quiet_assets</code> gem in our application. It turns off the Rails asset pipeline log in development mode.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2016/09/02/rails-5-silences-assets-logs-in-development-mode-by-default.html">Rails 5 silences assets logs</a></p>]]></description><link>https://midhunkrishna.in/untitled/</link><guid isPermaLink="false">5f3a83b40379ed43f3a78a54</guid><category><![CDATA[rails]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Fri, 02 Sep 2016 05:30:00 GMT</pubDate><content:encoded><![CDATA[<p>As a Rails developer, it was a familiar picture of assets logs flooding the whole terminal in development mode. Fortunately, we could include <code>quiet_assets</code> gem in our application. It turns off the Rails asset pipeline log in development mode.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2016/09/02/rails-5-silences-assets-logs-in-development-mode-by-default.html">Rails 5 silences assets logs in dev mode by default</a></p>]]></content:encoded></item><item><title><![CDATA[Rails 5 Expression Indexes & Operator Classes support]]></title><description><![CDATA[<p>Let’s assume that in our health care application we have a page which shows all Patients. This page also has a filter and it allows us to filter patients by their name.</p><p>We could implement the filter as shown here.</p><pre><code class="language-ruby">Patient.where("lower(first_name) = ?", first_name.downcase)</code></pre><p>Read</p>]]></description><link>https://midhunkrishna.in/rails-5-expression-indexes-operator-classes-support/</link><guid isPermaLink="false">5f3a842a0379ed43f3a78a69</guid><category><![CDATA[rails]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Wed, 20 Jul 2016 06:30:00 GMT</pubDate><content:encoded><![CDATA[<p>Let’s assume that in our health care application we have a page which shows all Patients. This page also has a filter and it allows us to filter patients by their name.</p><p>We could implement the filter as shown here.</p><pre><code class="language-ruby">Patient.where("lower(first_name) = ?", first_name.downcase)</code></pre><p>Read more about this at: <a href="https://blog.bigbinary.com/2016/07/20/rails-5-adds-support-for-expression-indexes-for-postgresql.html">Rails 5 Expression Indexes &amp; Operator Classes support</a></p>]]></content:encoded></item><item><title><![CDATA[Attach arbitrary metadata to an Active Job in Rails 5]]></title><description><![CDATA[<p>Rails 4.2 came with built-in support for executing jobs in the background using Active Job. Along with many enhancements to Active Job, Rails 5 provides the ability to <a href="https://github.com/rails/rails/pull/18260">attach arbitrary metadata to any job</a>.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2016/07/18/attach-arbitrary-metadata-to-an-active-job-in-rails-5.html">Attach arbitrary metadata to an Active Job in Rails 5</a></p>]]></description><link>https://midhunkrishna.in/attach-arbitrary-metadata-to-an-active-job-in-rails-5/</link><guid isPermaLink="false">5f3a848a0379ed43f3a78a77</guid><category><![CDATA[rails]]></category><dc:creator><![CDATA[Midhun Krishna]]></dc:creator><pubDate>Sat, 16 Jul 2016 13:22:00 GMT</pubDate><content:encoded><![CDATA[<p>Rails 4.2 came with built-in support for executing jobs in the background using Active Job. Along with many enhancements to Active Job, Rails 5 provides the ability to <a href="https://github.com/rails/rails/pull/18260">attach arbitrary metadata to any job</a>.</p><p>Read more about this at: <a href="https://blog.bigbinary.com/2016/07/18/attach-arbitrary-metadata-to-an-active-job-in-rails-5.html">Attach arbitrary metadata to an Active Job in Rails 5</a></p>]]></content:encoded></item></channel></rss>