Otevře se na nové kartě
Všechny články
8. 6. 2014
8 minut čtení

Co je config.threadsafe!

Všichni máme rádi Rails pro jeho eleganci a podporu různých featur, nehledě na to, že drží krok s dnešním technologickým věkem a neustále se inovuje a přináší nové možnosti. Rails umožňuje vývojáři, aby se soustředil na skutečnou práci a neřešil zbytečně problémy samotného jazyka a  jak některé věci vůbec nastavit apod. Dává přednost konvenci před konfigurací.

Toto může však pro někoho znamenat i komplikaci, protože Rails framework skrývá většinu konfigurace ve svém nitru a bere je jako výchozí. Pokud chce vývojář dosáhnout určitých větších změn a nastavení, musí vědět jak na to, nebo kde si to najít. Začínající vývojáři obvykle mají problém v porozumění konceptu Rails, jako je Rack, Rack Middleware, ActiveRecord, Asset Pipeline, thread safety apod. V tomto článku se budu věnovat práve thread safety. 

Co to je vlastně multithreading

Multithreading je velmi důležitý koncept v počítačové vědě a měli bychom mu dávat větší pozornost. Jedná se o vícevláknové zpracovávání určitého kusu programového kódu, instrukcí, nezávisle na sobě, kdy požadavky na procesor probíhají paralelně. Využití můžeme najít například při zpracování mnohdy dlouhých tásků, které probíhají asynchronně na pozadí. 

Jak to tedy funguje v Ruby on Rails? Thread safety bylo zavedeno do Railsů již od verze 2.3. Znamená to, že pokud máme web server podporující multivlákna, tak náš kód by měl být thread safe. Pokud na naši aplikaci přistupuje více vláken najednou, tak by naše sdílená data neměla být poškozena, jakmile všechny vlákna skončí.

Jak nám tedy Rails zaručí, aby naše aplikace byla thread safe?

Rails ve výchozím stavu přidávají middleware, který se nazývá “Rack::Lock”. Tento middleware je druhý v pořadí v balíčku výchozích middlewarů. Pokud chcete vypsat všechny middleware, které vaše aplikace využívá, stačí napsat příkaz rake middleware ve vašem rootu aplikace.

První middleware s názvem ActionDispatch::Static je využíván k servírování statických assetů jako jsou JavaScript, CSS a obrázky.

Rack::Lock nám garantuje, že bude spouštěno pouze jedno vlákno v jeden daný okamžik. Pokud tento middleware odstraníme, potom bude v jednom stejném čase spouštěno více vláken. MRI Ruby má mechanizmus nazývaný GIL (Global Interpreter Lock) nebo GVL (Global VM Lock / Giant VM Lock) od verze Ruby 1.9. GIL nám také garantuje že v jeden okamžik bude spouštěno jen jedno vlákno, ale navíc má funkci kontextového přepínání. Ruby je na tolik inteligentní, že dokáže spustit proces, pokud jiný proces čeká na nějakou operaci, aby mohl být dokončen.

Pojďme se podívat na příklad thread safety aplikace v Rails.

Vytvoříme Rails aplikaci.

rails new test_app

Nyní přistupme do složky s projektem a spusťme bundle pro nainstalování nezbytných gemů.

bundle

Poté vygenerujeme kontroller s pár akcemi.

rails generate controller thread_safety index simple infinite

Tento příkaz vygeneruje kontoller ThreadSafetyController s akcemi index, simple a infinite. Otevřeme šablonu umístěnou v app/views/thread_safety/index.html.erb a nakopírujeme tam následující kód:

<button id="simple_request">Simple Request</button>
<button id="infinite_request">Infinite Request</button>
<script>// <![CDATA[
$("#simple_request").click(function() {
$.get("/users/simple", function(data) {
alert(data)
});
});
$("#infinite_request").click(function() {
$.get("/users/infinite", function(data) {
alert(data)
});
});
// ]]></script>

To nám vytvoří stránku s dvěma tlačítky, jejichž účelem je poslat Ajax požadavky našim akcím v controlleru a zobrazit data v alert boxu.

Nyní přidáme trochu kódu do našeho controlleru umístěného v app/controllers/thread_safety_controller.rb

def simple
sleep(1)
render :text => "Welcome from simple method"
end
def infinite
while true
end
end

Kód uvedený výše je velmi jednoduchý. metoda simple spí 1 sekundu a poté vrátí obyčejný text klientovi, avšak metoda infinite má nekonečnou smyčku a nevrátí nikdy nic, protože bude probíhat donekonečna. Nastartujte server napsáním rails s a přejděte na adresu http://localhost:3000/thread_safety/index

Klikněte na tlačítko “Simple Request” a po vteřině dostanete odpověď v alert boxu ze serveru. Nyní klikněte na tlačítko “Infinite Request” a počkejte na odpověď.

Metoda infinite nikdy nevrátí výsledek, kvůli nekonečné smyčce. Zmáčkněte “Simple Request” znovu. Pokud očekáváte odpověď ze serveru jako před chvílí, pletete se :-).

Toto je thread safety. Rails nám garantuje, že bude naše aplikace v tomto bezpečná, tím, že spustí pouze jeden požadavek v jednom okamžiku. Žádná další vlákna nespustí, dokud nedokončí již běžící proces.

Pokud spustíme aplikaci v produkčním režimu, dostaneme stejný výsledek. Toto je dobré a správné chování, protože nám Rails zajišťuje bezpečný kód.

Ale je tu problém

Pokud jste tuto aplikaci nasadili na produkční server s použitím webového serveru WEBrick (což byste neměli), pak vaši uživatelé můžou mít s webem problémy, protože bude v jeden čas obsloužen pouze jeden dotaz v jednom vlákně. Pokud některé z vláken bude trvat delší dobu, potom ostatní vlákna budou čekat. Toto řešení bude uživatele otravovat.

Naše assety budou serverem vydávány ihned, protože se jich toto nastavení netýká. Assety obsluhuje middleware ActionDispatch::Static, čili jeden daný asset bude vydáván několika uživatelům naráz ve stejnou dobu.

Jak tedy můžeme zprostředkovat požadavky bez blokace těch ostatních? Můžeme jednoduše zapnout config.threadsafe! v development.rb nebo production.rb souboru. Když tuto volbu povolíme, způsobí to v naší aplikaci masivní změnu!

Nyní můžete klikat na tlačítko „Simple“ vícekrát po stisknutí tlačítka „Infinite“ a server bude vracet výsledky. Zapli jsme podporu multithreadingu, ale nyní je naše zodpovědnost, abychom psali bezpečný kód.

V tomto článku jsme si ukázali koncept thread safety v Ruby on Rails. V reálných aplikacích tomu však je jinak. Můžete použít process-based webové servery pro reprodukci násobných požadavků i s vypnutou volbou config.threadsafe! Mezi tyto webové servery patří např. Unicorn nebo Passenger. Je tomu tak, protože process-based webové servery vytvářejí tzv. workery, kde každý z nich drží instanci vaší aplikace, a proto server dokáže obsloužit několik požadavků naráz.

Máte projekt?
Ozvěte se nám a probereme, jak vám můžeme pomoci.
Napište nám
Další články
12. 10. 2026

Seznam Event Measurement (SEM) na Wontilles. Přesné měření bez starostí

Digitální marketing prochází zásadní proměnou. Zpřísňující se ochrana osobních údajů, postupný konec souborů cookie třetích stran a stoupající obliba nástrojů pro blokování skriptů staví provozovatele e-shopů před novou výzvu. Bez spolehlivých dat o chování uživatelů je efektivní řízení výkonnostních kampaní prakticky nemožné. Reklamní systém Sklik proto přichází s novým standardem v podobě Seznam Event Measurement…
Přečíst článek
2. 10. 2026

Filatika: moderní technologie pro svět poštovních známek

Filatelie spojuje historii, detailní znalosti i radost z objevování. Současně však přináší výzvy: rozpoznat konkrétní emisi či variantu známky, ověřit její pravost nebo přesně evidovat jednotlivé položky ve sbírce často vyžaduje mnoho zkušeností a pečlivé odborné posouzení. Proto zahajujeme projekt Filatika, jehož cílem je vyvinout integrovanou technologickou platformu pro přesnou, reprodukovatelnou a odborně ověřitelnou identifikaci,…
Přečíst článek
16. 9. 2026

Nová verze aplikace Dny NATO

Ve spolupráci s Dny NATO v Ostravě & Dny Vzdušných sil AČR jsme vydali novou verzi mobilní aplikace Dny NATO, která návštěvníkům usnadní orientaci v programu i areálu akce. Aplikace nabízí aktuální program dynamických ukázek, přehled plánovaných příletů a odletů, interaktivní mapu areálu i informace o statických ukázkách v jednotlivých prezentačních zónách. Díky napojení na…
Přečíst článek