Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Modern Concurrency Practices in Ruby
Search
Arnab Deka
June 20, 2014
Technology
73
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Modern Concurrency Practices in Ruby
Presented at RuLu'14:
http://rulu.eu/speakers/#arnab
Arnab Deka
June 20, 2014
More Decks by Arnab Deka
See All by Arnab Deka
Requiem for a dream
orknob
0
62
Other Decks in Technology
See All in Technology
AIカンパニーへの転換を支えた、エンジニアの仕事の再定義
kworkdev
PRO
2
1.2k
パッチ更新でterraform initが落ちた日
grimoh
1
140
初海外で注意すべきこと12選!!!安全快適なre:invent生活にするために
yuuuuuuu168
1
160
hackers_champloo_2026_tidb
makocchi
0
160
夫婦で子育てするための育児標準化
codmoninc
PRO
0
340
会社説明資料
persolserverworks
0
9.8k
スプシの手作業からの解脱 ~更新はClaude Codeに、見せ方と使い方はGASアプリに任せる~
kentarofujii
0
150
サブエージェントと Claude Mods で作る独自 Advisor ツールの話
kenichiodo
2
160
V8のArray.prototype.flatを最大約20倍速くするまでと、巨大OSSへの大規模コミットの道のり
riyaamemiya
0
290
20261017福岡devIO 「AIは"良いダッシュボード"を作れるか?
jtakeda
0
140
コンテナ運用におけるネットワーク・コンテナコストの削減方法/How to Reduce Network and Container Costs in Container Operations
masakiokuda
1
150
今さら理解するウェブフォントver.2026
takanorip
3
770
Featured
See All Featured
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
How STYLIGHT went responsive
nonsquared
100
6.3k
Scaling GitHub
holman
464
140k
Building Applications with DynamoDB
mza
96
7.2k
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
59k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
300
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Building AI with AI
inesmontani
PRO
1
1.3k
Faster Mobile Websites
deanohume
310
32k
The SEO Collaboration Effect
kristinabergwall1
1
590
Transcript
Modern Concurrency Practices in Ruby @arnab_deka
None
None
None
None
Agenda I would remove the thread and add actors or
some other more advanced concurrency features — Matz
Agenda... 4 Elixir 4 Clojure 4 Go 4 Of course,
Ruby ... 4 Even some French!
Agenda... 4 Elixir 4 Clojure 4 Go 4 Of course,
Ruby ... 4 Even some French! Sadly, NO Pascal
Arnab 4 @arnab_deka 4 http://arnab-deka.com/ 4 Assam > Kerala >
Pune > NYC > Seattle > Bangalore 4 Infosys/Goldman > Amazon > LivingSocial 4 C/C++ > Perl > Java > Ruby > Ruby/Clojure
None
None
None
Warm up class Counter attr_reader :count def initialize @count =
0 end def inc @count += 1 end end
Warm up... counter = Counter.new t1 = Thread.new { 1000.times
{ counter.inc } } t2 = Thread.new { 1000.times { counter.inc } } t1.join; t2.join puts "Final count: #{counter.count}"
Solution? Mutexes! Of course!
Solution? Mutexes! But... 4 testing? 4 debugging? 4 waking up
at 3 AM to solve that Race condition?
None
STM
STMs: sidetrack on atoms 4 Compare and Swap 4 Lock-free
4 Non-blocking
None
STMs: sidetrack on atoms... require 'atomic' class Counter def initialize
@count = Atomic.new(0) end def inc @count.update { |num| num + 1 } end def count @count.value end end
STMs: sidetrack on atoms... counter = Counter.new t1 = Thread.new
{ 1000.times { counter.inc } } t2 = Thread.new { 1000.times { counter.inc } } t1.join; t2.join puts "Final count, using atomic: #{counter.count}"
STM... (def transfer-count (atom 0)) (let [fn-nonnegative #(>= % 0)]
(def alice (ref 1000 :validator fn-nonnegative)) (def bob (ref 2000 :validator fn-nonnegative)))
STM... (defn transfer [from to amount] (dosync (swap! transfer-count inc)
(alter from - amount) (alter to + amount)))
STM... (repeatedly 25 #(transfer alice bob 100)) => IllegalStateException (println[@alice
@bob @transfer-count]) ;; => [0 3000 11]
STM... ✔Atomic
STM... ✔Atomic ✔Consistent
STM... ✔Atomic ✔Consistent ✔Isolated
STM... ✔Atomic ✔Consistent ✔Isolated But... ✘ Durable
STM... 4 Synchronous 4 Retries...
STMs in Ruby??? :(
STMs in Ruby??? Alternatives... 4 HTM 4 Intel's Transactional Synchronization
Extensions 4 PyPy's Transactional Memory 4 Atoms
counting.rubis classe Compteur attr_lire :recenser définir initialiser @recenser = 0
fin définir accroissement @recenser += 1 fin fin
Step 1 1763: French Indian War
Step 2 East India Companies: French > Brits
None
None
French in the US and in India... 4 ENIEO, not
ENIAC 4 La sous-traitance, not "outsourcing" 4 ... 4 ... 4 ... 4 "Le Rubis", not Ruby
None
Actors
WHAT OOP WAS MEANT TO BE.
Actors in Elixir defmodule Player do def play(name) do receive
do {:serve} -> # do it ... end end end p1 = spawn_link(Player, :play, ["Djokovic"]) send(p1, {:serve}) # or register to a name Process.register(p1, :djoker) send(:djoker, {:serve})
Actors in Ruby class Player include Celluloid def initialize(name); end
def serve; end end djoker = Player.new djoker.async.serve Player.supervise_as(:djoker, "Djokovic") Celluloid::Actor[:djoker].async.serve
Erlang/Elixir: there's more... 4 Processes are very very light-weight
Erlang/Elixir: there's more... 4 Processes are very very light-weight 4
fault-tolerance: let it crash
Erlang/Elixir: there's more... 4 Processes are very very light-weight 4
fault-tolerance: let it crash 4 OTP framework
Erlang/Elixir: there's more... 4 Processes are very very light-weight 4
fault-tolerance: let it crash 4 OTP framework 4 Distributed
What about Ruby? 4 Celluloid 4 DCell
Actors in Ruby: DCell 4 Over 0mq require 'dcell' DCell.start
:id => "itchy", :addr => "tcp://127.0.0.1:9001" DCell.start :id => "scratchy", :addr => "tcp://127.0.0.1:9002" itchy_node = DCell::Node["itchy"]
Channels
Actors 4 focus: named processes/actors 4 coupled to message format
Channels 4 focus: transport, not receiver 4 anything can produce/consume
side-track: #golang board := make([][]string, m) for i := range
board { board[i] = make([]string, n) }
side-track: #golang board = Array.new(Array.new)
core.async (def c (chan)) (thread (println "Pouring: " (<!! c)
" from channel")) (>!! c "Hello RuLu")
core.async: buffering 4 unbuffered by default. Will block on 4
reading from empty channels 4 writing to non-empty channels
core.async: buffering 4 will buffer upto n: (def bc (chan
20)) (>!! bc "Hello") (>!! bc "RuLu") (<!! bc) ;;; "Hello" (<!! bc) ;;; "RuLu"
core.async: buffering 4 dropping channels (def c (chan (dropping-buffer 20)))
4 sliding channels (def c (chan (sliding-buffer 20))) 4 Why not handle buffering automatically?
core.async: channel functions 4 map-chan 4 onto-chan 4 ...
core.async: go blocks (def c (chan)) (go (let [x (<!
c) y (<! c)] (println (clojure.string/join " " [x y])))) (>!! c "Hello") (>!! c "RuLu!")
None
Channels in Ruby require 'jo' include Jo c = chan
jo do x = c.take y = c.take puts (x + y) end c << 10 c << 25
Closing thoughts & Advice
Experiment
Keep it simple
None
Resources 4 github: arnab/modern-concurrency-rulu 4 presentation/resources.md
RuLu