{"id":3368,"date":"2012-12-19T14:24:34","date_gmt":"2012-12-19T11:24:34","guid":{"rendered":"http:\/\/railsware.com\/blog\/?p=3368"},"modified":"2021-08-12T17:59:53","modified_gmt":"2021-08-12T14:59:53","slug":"fixing-multithreading-for-rails-in-development-mode","status":"publish","type":"post","link":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/","title":{"rendered":"Fixing multithreading for Rails in development mode"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Preface<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Rails, automatic code reloading in development mode is based on <a title=\"autoload\" href=\"http:\/\/www.rubyinside.com\/ruby-techniques-revealed-autoload-1652.html\" target=\"_blank\" rel=\"noopener noreferrer\">autoload<\/a>,<br>which is not threadsafe. It means you can&#8217;t use it while developing multithreaded Rails applications(especially for JRuby). But several monkeypatches can do the trick.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Workaround<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When we discovered this limitation almost a year ago, we had next options:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>development without code reloading and restart server after every change<\/li><li>fix autoload threadsafe issue<\/li><li>create some workaround<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">As any RoR developer, I can&#8217;t imagine my life without automatic code<br>reloading, so server restart was not an option.<br>Fixing autoload is a nontrivial task. Corresponded bug was reported 4<br>years ago, and still wasn&#8217;t fixed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, the only choice we had is to create some workaround. Solution<br>quickly came to mind &#8211; simply don&#8217;t use multithreading in development mode. We created fallback which made our application logic work in single-threaded mode for development, and in multithreaded mode for production.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fix of autoload<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After 4 years of struggling, autoload was <a title=\"autoload fix discussion\" href=\"http:\/\/bugs.ruby-lang.org\/issues\/921\" target=\"_blank\" rel=\"noopener noreferrer\">fixed in ruby-trunk<\/a>. It&#8217;s<br>scheduled to be delivered with Ruby 1.9.4 at the beginning of 2013. Luckily for us, patch was ported into JRuby 1.6.6, so we don&#8217;t have to wait till Christmas.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rvm install jruby-1.6.7\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then I disabled our fallback for development mode, and &#8230; found out that server crashed repeatedly across different places. Switching to production mode instantly fixed all exceptions. It looks like threadsafety of autoload was not the only issue.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Digging into Rails guts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every exception was different, but in most cases it was database<br>related issue. E.g. some objects in database were missing, some were not updated, deadlocking of SQL-queries and so on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I started with grep-ing database query logs. Very soon quite weird behavior was observed: bunch of SQL-queries from one controller action were handled by different database connections. But they all should be issued by only one AR-connection!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After this finding, the main suspect became infamous ActiveRecord::ConnectionAdapters::ConnectionPool. Again! In case you<br>don&#8217;t know, ConnectionPool is not threadsafe in Rails &lt; 3.2.4, so we already had<br><a title=\"monkeypatch\" href=\"https:\/\/gist.github.com\/2658680\" target=\"_blank\" rel=\"noopener noreferrer\">monkeypatch<\/a> for it.<br>After adding some traces to ConnectionPool <em>.checkin<\/em> and <em>.checkout<\/em><br>methods, we got next flow:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"319\" height=\"252\" src=\"\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic1_v21.png\" alt=\"\" class=\"wp-image-3411\" title=\"code_reload_blog_pic1_v2\" srcset=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic1_v21.png 319w, https:\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic1_v21-300x236.png 300w\" sizes=\"auto, (max-width: 319px) 100vw, 319px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But why was connection checked-in in the middle of job processing?<br><em>ConnectionPool<\/em> has <a title=\"ConnectionPool\" href=\"http:\/\/api.rubyonrails.org\/classes\/ActiveRecord\/ConnectionAdapters\/ConnectionPool.html\" target=\"_blank\" rel=\"noopener noreferrer\">3 working strategies<\/a>, and<br>we used the simplest one. Connection is checked-out on demand, and when controller action is done, all connections used by<br>current thread are checked-in by <em>clear_active_connections!<\/em> method.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But in development mode something checks-in connections while they are actively used. Such behavior may not affect some applications, but with active usage of database transactions, which are bound to db-connections, disaster is guaranteed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are just a few methods in ActiveRecord, which checkin\/checkout connections. Putting several additional traces I got next flow:<br><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3394\" title=\"code_reload_blog_pic2_v2\" src=\"\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic2_v2.png\" alt=\"\" width=\"773\" height=\"375\" srcset=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic2_v2.png 773w, https:\/\/railsware.com\/blog\/wp-content\/uploads\/2012\/11\/code_reload_blog_pic2_v2-300x145.png 300w\" sizes=\"auto, (max-width: 773px) 100vw, 773px\" \/><br>Connections were checked-in by clear_reloadable_connections! which is<br>called after processing of every request in development mode. Here is how it looks:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def clear_reloadable_connections!\n  #this part checkin all checked-out connections even used by other threads!\n  @reserved_connections.each do |name, conn|\n    checkin conn\n  end\n  @reserved_connections = {}\n  #this part disconnects all conections which requires reloading.\n  @connections.each do |conn|\n    conn.disconnect! if conn.requires_reloading?\n  end\n  @connections.delete_if do |conn|\n    conn.requires_reloading?\n  end\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It can be split in two parts. First one is the root of our issue: it simply checks-in all active connections from all threads, no matter they are used or not. So why is it so lame? Git-blame shows, that this method was <a href=\"https:\/\/github.com\/rails\/rails\/commit\/0a86122a248020081722bf0c12de70c929cbcbd9\" target=\"_blank\" rel=\"noopener noreferrer\">added 6 years ago<\/a>. Commit message says &#8220;Only reload connections in development mode that supports (and requires that) &#8212; in other words, only do it for SQLite&#8221;.<br>And here is how it looked 6 years ago:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def clear_reloadable_connections!\n  @@active_connections.each do |name, conn|\n    conn.disconnect! if conn.supports_reloading?\n    @@active_connections.delete(name)\n  end\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A bit simplier, but it does two things:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>disconnects SQLite connections(.support_reloading? method returns true only for SQLite connection)<\/li><li>checks-in ALL connections without any respect to other threads<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Before this commit, instead of <em>clear_reloadable_connections!<\/em> another<br>method was called: <em>clear_active_connections!<\/em>, which was:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def clear_active_connections!\n  clear_cache!(@@active_connections) do |name, conn|\n    conn.disconnect!\n  end\nend\n\ndef clear_cache!(cache, thread_id = nil, &amp;block)\n  if cache\n    if @@allow_concurrency\n      thread_id ||= Thread.current.object_id \n        #in multithreaded environment it will work only with current thread,\n        #leaving others threads cache intact\n      thread_cache, cache = cache, cache[thread_id]\n      return unless cache\n    end\n\n    cache.each(&amp;block) if block_given?\n    cache.clear\n  end\nensure\n  if thread_cache &amp;&amp; @@allow_concurrency\n    thread_cache.delete(thread_id)\n  end\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike <em>clear_reloadable_connections!<\/em>, this one respects other threads and clears connections used by current thread only. Looks like <em>clear_reloadable_connections!<\/em> was de-threadsafed unintentionally and this should be fixed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If we don&#8217;t use SQLite why bother ourselves with fix for <em>clear_reloadable_connections!<\/em>? Instead we can just disable it :). Here is a dumbest monkey-patch:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class ActiveRecord::ConnectionAdapters::ConnectionPool\n  def clear_reloadable_connections!;end \n  # disable it, since it checks-in ALL connections from ALL threads after every request\n  # in development mode\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We have like 5 minutes to celebrate the victory, but ActiveRecord::ConnectionTimeoutError, &#8220;could not obtain a database connection within 5 seconds&#8221; brings us back to earth. Looks like database connections leak from ConnectionPool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Further digging showed that WEBrick leaks connections when exception is raised (like RoutingError). Nobody noticed this because <em>clear_reloadable_connections!<\/em> checks-out all connections after every request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">ActiveRecord has special method &#8211; <a href=\"http:\/\/api.rubyonrails.org\/classes\/ActiveRecord\/ConnectionAdapters\/ConnectionPool.html#method-i-clear_stale_cached_connections-21\" target=\"_blank\" rel=\"noopener noreferrer\">clear_stale_cached_connections!<\/a>.<br>It checks-in all leaked connections from dead threads, leaving active intact. Easiest place to call it is at the beginning of the <em>checkout<\/em> method:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class ActiveRecord::ConnectionAdapters::ConnectionPool\n  def checkout\n    clear_stale_cached_connections! if Rails.env.development? #hack for WEBrick\n    ...\n  end\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Voila! We have multithreaded application running in development mode with code reload!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To make code reloading work in multithreaded mode you need:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>JRuby &gt;= 1.6.6 or MRI &gt;= 1.9.4, where autoload threadsafety is fixed<\/li><li>monkeypatch ConnectionPool to disable clear_reloadable_connections!<\/li><li>monkeypatch ConnectionPool to deal with connections leakage in WEBrick<\/li><li>update to Rails &gt;= 3.2.4, where <a href=\"http:\/\/bibwild.wordpress.com\/2012\/03\/15\/activerecord-concurrency-currently-good-news-and-bad\/\" target=\"_blank\" rel=\"noopener noreferrer\">threadsafety issues<\/a> with ConnectionPool is fixed<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Preface In Rails, automatic code reloading in development mode is based on autoload,which is not threadsafe. It means you can&#8217;t use it while developing multithreaded Rails applications(especially for JRuby). But several monkeypatches can do the trick. Workaround When we discovered this limitation almost a year ago, we had next options: development without code reloading and&#8230;<\/p>\n","protected":false},"author":43,"featured_media":9452,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[3],"tags":[],"coauthors":["Oleksandr Bondar"],"class_list":["post-3368","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.9 - aioseo.com -->\n\t<meta name=\"description\" content=\"Multithreading for Rails in development mode doesn&#039;t work. But it can be fixed.\" \/>\n\t<meta name=\"robots\" content=\"max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n\t<meta name=\"author\" content=\"Oleksandr Bondar\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.9\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"| Blog on Engineering, Product Management, Transparency, Culture and many more...\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Fixing multithreading for Rails in development mode | Railsware Blog\" \/>\n\t\t<meta property=\"og:description\" content=\"Multithreading for Rails in development mode doesn&#039;t work. But it can be fixed.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"360\" \/>\n\t\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2012-12-19T11:24:34+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2021-08-12T14:59:53+00:00\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#article\",\"name\":\"Fixing multithreading for Rails in development mode | Railsware Blog\",\"headline\":\"Fixing multithreading for Rails in development mode\",\"author\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/author\\\/oleksandr-bondar\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/Fixing-multithreading.png\",\"width\":360,\"height\":360,\"caption\":\"Fixing multithreading for Rails\"},\"datePublished\":\"2012-12-19T14:24:34+03:00\",\"dateModified\":\"2021-08-12T17:59:53+03:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#webpage\"},\"articleSection\":\"Engineering\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/railsware.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/category\\\/development\\\/#listItem\",\"name\":\"Engineering\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/category\\\/development\\\/#listItem\",\"position\":2,\"name\":\"Engineering\",\"item\":\"https:\\\/\\\/railsware.com\\\/blog\\\/category\\\/development\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#listItem\",\"name\":\"Fixing multithreading for Rails in development mode\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#listItem\",\"position\":3,\"name\":\"Fixing multithreading for Rails in development mode\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/category\\\/development\\\/#listItem\",\"name\":\"Engineering\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/#organization\",\"description\":\"Blog on Engineering, Product Management, Transparency, Culture and many more...\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/11\\\/Logo-circle.png\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#organizationLogo\",\"width\":3137,\"height\":1054,\"caption\":\"Railsware logo\"},\"image\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#organizationLogo\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/author\\\/oleksandr-bondar\\\/#author\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/author\\\/oleksandr-bondar\\\/\",\"name\":\"Oleksandr Bondar\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#authorImage\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/author-image-default-96x96.jpg\",\"width\":96,\"height\":96,\"caption\":\"Oleksandr Bondar\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#webpage\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/\",\"name\":\"Fixing multithreading for Rails in development mode | Railsware Blog\",\"description\":\"Multithreading for Rails in development mode doesn't work. But it can be fixed.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/author\\\/oleksandr-bondar\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/author\\\/oleksandr-bondar\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/Fixing-multithreading.png\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#mainImage\",\"width\":360,\"height\":360,\"caption\":\"Fixing multithreading for Rails\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/fixing-multithreading-for-rails-in-development-mode\\\/#mainImage\"},\"datePublished\":\"2012-12-19T14:24:34+03:00\",\"dateModified\":\"2021-08-12T17:59:53+03:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/railsware.com\\\/blog\\\/\",\"description\":\"Blog on Engineering, Product Management, Transparency, Culture and many more...\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/railsware.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Fixing multithreading for Rails in development mode | Railsware Blog","description":"Multithreading for Rails in development mode doesn't work. But it can be fixed.","canonical_url":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/","robots":"max-snippet:-1, max-image-preview:large, max-video-preview:-1","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#article","name":"Fixing multithreading for Rails in development mode | Railsware Blog","headline":"Fixing multithreading for Rails in development mode","author":{"@id":"https:\/\/railsware.com\/blog\/author\/oleksandr-bondar\/#author"},"publisher":{"@id":"https:\/\/railsware.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png","width":360,"height":360,"caption":"Fixing multithreading for Rails"},"datePublished":"2012-12-19T14:24:34+03:00","dateModified":"2021-08-12T17:59:53+03:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#webpage"},"isPartOf":{"@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#webpage"},"articleSection":"Engineering"},{"@type":"BreadcrumbList","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/railsware.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog\/category\/development\/#listItem","name":"Engineering"}},{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog\/category\/development\/#listItem","position":2,"name":"Engineering","item":"https:\/\/railsware.com\/blog\/category\/development\/","nextItem":{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#listItem","name":"Fixing multithreading for Rails in development mode"},"previousItem":{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#listItem","position":3,"name":"Fixing multithreading for Rails in development mode","previousItem":{"@type":"ListItem","@id":"https:\/\/railsware.com\/blog\/category\/development\/#listItem","name":"Engineering"}}]},{"@type":"Organization","@id":"https:\/\/railsware.com\/blog\/#organization","description":"Blog on Engineering, Product Management, Transparency, Culture and many more...","url":"https:\/\/railsware.com\/blog\/","logo":{"@type":"ImageObject","url":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2020\/11\/Logo-circle.png","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#organizationLogo","width":3137,"height":1054,"caption":"Railsware logo"},"image":{"@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#organizationLogo"}},{"@type":"Person","@id":"https:\/\/railsware.com\/blog\/author\/oleksandr-bondar\/#author","url":"https:\/\/railsware.com\/blog\/author\/oleksandr-bondar\/","name":"Oleksandr Bondar","image":{"@type":"ImageObject","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#authorImage","url":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2021\/06\/author-image-default-96x96.jpg","width":96,"height":96,"caption":"Oleksandr Bondar"}},{"@type":"WebPage","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#webpage","url":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/","name":"Fixing multithreading for Rails in development mode | Railsware Blog","description":"Multithreading for Rails in development mode doesn't work. But it can be fixed.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/railsware.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#breadcrumblist"},"author":{"@id":"https:\/\/railsware.com\/blog\/author\/oleksandr-bondar\/#author"},"creator":{"@id":"https:\/\/railsware.com\/blog\/author\/oleksandr-bondar\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png","@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#mainImage","width":360,"height":360,"caption":"Fixing multithreading for Rails"},"primaryImageOfPage":{"@id":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/#mainImage"},"datePublished":"2012-12-19T14:24:34+03:00","dateModified":"2021-08-12T17:59:53+03:00"},{"@type":"WebSite","@id":"https:\/\/railsware.com\/blog\/#website","url":"https:\/\/railsware.com\/blog\/","description":"Blog on Engineering, Product Management, Transparency, Culture and many more...","inLanguage":"en-US","publisher":{"@id":"https:\/\/railsware.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"| Blog on Engineering, Product Management, Transparency, Culture and many more...","og:type":"article","og:title":"Fixing multithreading for Rails in development mode | Railsware Blog","og:description":"Multithreading for Rails in development mode doesn't work. But it can be fixed.","og:url":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/","og:image":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png","og:image:secure_url":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png","og:image:width":360,"og:image:height":360,"article:published_time":"2012-12-19T11:24:34+00:00","article:modified_time":"2021-08-12T14:59:53+00:00"},"aioseo_meta_data":{"post_id":"3368","title":"Fixing multithreading for Rails in development mode | Railsware Blog","description":"Multithreading for Rails in development mode doesn't work. But it can be fixed.","keywords":[],"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-6385f5b11a9f1","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":{"locations":{"business":{"name":"","businessType":"","image":"","areaServed":"","urls":{"website":"","aboutPage":"","contactPage":""},"address":{"streetLine1":"","streetLine2":"","zipCode":"","city":"","state":"","country":"","addressFormat":"#streetLineOne\n#streetLineTwo\n#city, #state #zipCode"},"contact":{"email":"","phone":"","phoneFormatted":"","fax":"","faxFormatted":""},"ids":{"vat":"","tax":"","chamberOfCommerce":""},"payment":{"priceRange":"","currenciesAccepted":"","methods":""}}},"openingHours":{"useDefaults":true,"show":true,"alwaysOpen":false,"use24hFormat":false,"timezone":"","labels":{"closed":"","alwaysOpen":""},"days":{"monday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"tuesday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"wednesday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"thursday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"friday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"saturday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"sunday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"}}}},"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-01-04 12:44:28","updated":"2025-09-26 11:16:39","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/railsware.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/railsware.com\/blog\/category\/development\/\" title=\"Engineering\">Engineering<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tFixing multithreading for Rails in development mode\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/railsware.com\/blog"},{"label":"Engineering","link":"https:\/\/railsware.com\/blog\/category\/development\/"},{"label":"Fixing multithreading for Rails in development mode","link":"https:\/\/railsware.com\/blog\/fixing-multithreading-for-rails-in-development-mode\/"}],"categories_data":[{"name":"Engineering","link":"https:\/\/railsware.com\/blog?category=development"}],"post_thumbnails":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/12\/Fixing-multithreading.png","article_background":"","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/3368","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/users\/43"}],"replies":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/comments?post=3368"}],"version-history":[{"count":110,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/3368\/revisions"}],"predecessor-version":[{"id":14019,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/3368\/revisions\/14019"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media\/9452"}],"wp:attachment":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media?parent=3368"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/categories?post=3368"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/tags?post=3368"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/coauthors?post=3368"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}